├── .ci-dockerfiles ├── alpine-bootstrap-tester │ ├── Dockerfile │ └── build-and-push.bash ├── alpine3.20-bootstrap-tester │ ├── Dockerfile │ └── build-and-push.bash ├── alpine3.21-bootstrap-tester │ ├── Dockerfile │ └── build-and-push.bash ├── fedora41-bootstrap-tester │ ├── Dockerfile │ └── build-and-push.bash ├── ubuntu22.04-bootstrap-tester │ ├── Dockerfile │ └── build-and-push.bash └── ubuntu24.04-bootstrap-tester │ ├── Dockerfile │ └── build-and-push.bash ├── .ci-scripts ├── macos-arm64-install-pony-tools.bash ├── macos-x86-install-pony-tools.bash ├── release │ ├── arm64-apple-darwin-nightly.bash │ ├── arm64-apple-darwin-release.bash │ ├── arm64-unknown-linux-nightly.bash │ ├── arm64-unknown-linux-release.bash │ ├── build-docker-images-on-release.bash │ ├── build-latest-docker-images.bash │ ├── config.bash │ ├── x86-64-apple-darwin-nightly.bash │ ├── x86-64-apple-darwin-release.bash │ ├── x86-64-unknown-linux-nightly.bash │ └── x86-64-unknown-linux-release.bash └── test-bootstrap.sh ├── .github ├── FUNDING.yml ├── linters │ └── .markdown-lint.yml └── workflows │ ├── add-discuss-during-sync.yml │ ├── announce-a-release.yml │ ├── breakage-against-linux-ponyc-latest.yml │ ├── breakage-against-macos-arm64-ponyc-latest.yml │ ├── breakage-against-macos-x86-ponyc-latest.yml │ ├── changelog-bot.yml │ ├── latest-docker-image.yml │ ├── lint-action-workflows.yml │ ├── nightlies.yml │ ├── pr.yml │ ├── prepare-for-a-release.yml │ ├── release-notes-reminder-bot.yml │ ├── release-notes.yml │ ├── release.yml │ └── remove-discuss-during-sync.yml ├── .gitignore ├── .markdownlintignore ├── .release-notes ├── 0.6.0.md ├── 0.6.1.md ├── 0.6.2.md ├── 0.6.3.md ├── 0.6.4.md ├── 0.6.5.md ├── 0.6.6.md ├── 0.6.7.md ├── 0.6.8.md ├── 0.6.9.md ├── 0.7.0.md ├── 0.8.0.md ├── 0.8.1.md ├── 0.8.2.md ├── 0.8.3.md ├── 0.8.4.md ├── 0.8.5.md ├── 0.8.6.md └── next-release.md ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── RELEASE_PROCESS.md ├── VERSION ├── cmd ├── cli.pony ├── cloudsmith.pony ├── http_handlers.pony ├── main.pony ├── packages.pony ├── ponyup.pony └── version.pony.in ├── corral.json ├── make.ps1 ├── ponyup-init.ps1 ├── ponyup-init.sh └── test └── main.pony /.ci-dockerfiles/alpine-bootstrap-tester/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.20 2 | 3 | RUN apk add --update --no-cache \ 4 | binutils-gold \ 5 | build-base \ 6 | clang \ 7 | curl \ 8 | git \ 9 | libressl-dev \ 10 | make 11 | -------------------------------------------------------------------------------- /.ci-dockerfiles/alpine-bootstrap-tester/build-and-push.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o nounset 5 | 6 | # 7 | # *** You should already be logged in to GHCR when you run this *** 8 | # 9 | 10 | TODAY=$(date +%Y%m%d) 11 | DOCKERFILE_DIR="$(dirname "$0")" 12 | DOCKER_TAG="ghcr.io/ponylang/ponyup-ci-alpine-bootstrap-tester:${TODAY}" 13 | 14 | docker build --pull -t "${DOCKER_TAG}" "${DOCKERFILE_DIR}" 15 | docker push "${DOCKER_TAG}" 16 | -------------------------------------------------------------------------------- /.ci-dockerfiles/alpine3.20-bootstrap-tester/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.20 2 | 3 | LABEL org.opencontainers.image.source="https://github.com/ponylang/ponyup" 4 | 5 | RUN apk add --update --no-cache \ 6 | binutils-gold \ 7 | build-base \ 8 | clang \ 9 | curl \ 10 | git \ 11 | libressl-dev \ 12 | make 13 | -------------------------------------------------------------------------------- /.ci-dockerfiles/alpine3.20-bootstrap-tester/build-and-push.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o nounset 5 | 6 | # 7 | # *** You should already be logged in to GHCR when you run this *** 8 | # 9 | 10 | NAME="ghcr.io/ponylang/ponyup-ci-alpine3.20-bootstrap-tester" 11 | TODAY=$(date +%Y%m%d) 12 | DOCKERFILE_DIR="$(dirname "$0")" 13 | BUILDER="alpine3.20-builder-$(date +%s)" 14 | 15 | docker buildx create --use --name "${BUILDER}" 16 | docker buildx build --provenance false --sbom false --platform linux/arm64,linux/amd64 --pull --push -t "${NAME}:${TODAY}" "${DOCKERFILE_DIR}" 17 | docker buildx rm "${BUILDER}" 18 | -------------------------------------------------------------------------------- /.ci-dockerfiles/alpine3.21-bootstrap-tester/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.21 2 | 3 | LABEL org.opencontainers.image.source="https://github.com/ponylang/ponyup" 4 | 5 | RUN apk add --update --no-cache \ 6 | binutils-gold \ 7 | build-base \ 8 | clang \ 9 | curl \ 10 | git \ 11 | libressl-dev \ 12 | make 13 | -------------------------------------------------------------------------------- /.ci-dockerfiles/alpine3.21-bootstrap-tester/build-and-push.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o nounset 5 | 6 | # 7 | # *** You should already be logged in to GHCR when you run this *** 8 | # 9 | 10 | NAME="ghcr.io/ponylang/ponyup-ci-alpine3.21-bootstrap-tester" 11 | TODAY=$(date +%Y%m%d) 12 | DOCKERFILE_DIR="$(dirname "$0")" 13 | BUILDER="alpine3.21-builder-$(date +%s)" 14 | 15 | docker buildx create --use --name "${BUILDER}" 16 | docker buildx build --provenance false --sbom false --platform linux/arm64,linux/amd64 --pull --push -t "${NAME}:${TODAY}" "${DOCKERFILE_DIR}" 17 | docker buildx rm "${BUILDER}" 18 | -------------------------------------------------------------------------------- /.ci-dockerfiles/fedora41-bootstrap-tester/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM fedora:41 2 | 3 | RUN dnf install -y binutils-gold \ 4 | clang \ 5 | git \ 6 | lsb-release \ 7 | openssl-devel \ 8 | && dnf -y autoremove \ 9 | && dnf -y clean all \ 10 | && rm -rf /var/cache/dnf* 11 | 12 | RUN git config --global --add safe.directory /__w/ponyup/ponyup 13 | -------------------------------------------------------------------------------- /.ci-dockerfiles/fedora41-bootstrap-tester/build-and-push.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o nounset 5 | 6 | # 7 | # *** You should already be logged in to GHCR when you run this *** 8 | # 9 | 10 | TODAY=$(date +%Y%m%d) 11 | DOCKERFILE_DIR="$(dirname "$0")" 12 | DOCKER_TAG="ghcr.io/ponylang/ponyup-ci-fedora41-bootstrap-tester:${TODAY}" 13 | 14 | docker build --pull -t "${DOCKER_TAG}" "${DOCKERFILE_DIR}" 15 | docker push "${DOCKER_TAG}" 16 | -------------------------------------------------------------------------------- /.ci-dockerfiles/ubuntu22.04-bootstrap-tester/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:22.04 2 | 3 | RUN apt-get update \ 4 | && apt-get install -y --no-install-recommends \ 5 | ca-certificates \ 6 | clang \ 7 | curl \ 8 | git \ 9 | libssl-dev \ 10 | lsb-core \ 11 | make \ 12 | && rm -rf /var/lib/apt/lists/* 13 | 14 | RUN git config --global --add safe.directory /__w/ponyup/ponyup 15 | -------------------------------------------------------------------------------- /.ci-dockerfiles/ubuntu22.04-bootstrap-tester/build-and-push.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o nounset 5 | 6 | # 7 | # *** You should already be logged in to GHCR when you run this *** 8 | # 9 | 10 | TODAY=$(date +%Y%m%d) 11 | DOCKERFILE_DIR="$(dirname "$0")" 12 | DOCKER_TAG="ghcr.io/ponylang/ponyup-ci-ubuntu22.04-bootstrap-tester:${TODAY}" 13 | 14 | docker build --pull -t "${DOCKER_TAG}" "${DOCKERFILE_DIR}" 15 | docker push "${DOCKER_TAG}" 16 | -------------------------------------------------------------------------------- /.ci-dockerfiles/ubuntu24.04-bootstrap-tester/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:24.04 2 | 3 | LABEL org.opencontainers.image.source="https://github.com/ponylang/ponyup" 4 | 5 | RUN apt-get update \ 6 | && apt-get install -y --no-install-recommends \ 7 | ca-certificates \ 8 | clang \ 9 | curl \ 10 | git \ 11 | libssl-dev \ 12 | lsb-release \ 13 | make \ 14 | && rm -rf /var/lib/apt/lists/* 15 | 16 | RUN git config --global --add safe.directory /__w/ponyup/ponyup 17 | -------------------------------------------------------------------------------- /.ci-dockerfiles/ubuntu24.04-bootstrap-tester/build-and-push.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o nounset 5 | 6 | # 7 | # *** You should already be logged in to GHCR when you run this *** 8 | # 9 | 10 | NAME="ghcr.io/ponylang/ponyup-ci-ubuntu24.04-bootstrap-tester" 11 | TODAY=$(date +%Y%m%d) 12 | DOCKERFILE_DIR="$(dirname "$0")" 13 | BUILDER="ubuntu24.04-builder-$(date +%s)" 14 | 15 | docker buildx create --use --name "${BUILDER}" 16 | docker buildx build --provenance false --sbom false --platform linux/arm64,linux/amd64 --pull --push -t "${NAME}:${TODAY}" "${DOCKERFILE_DIR}" 17 | docker buildx rm "${BUILDER}" 18 | -------------------------------------------------------------------------------- /.ci-scripts/macos-arm64-install-pony-tools.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | case "${1}" in 4 | "release") 5 | REPO=releases 6 | ;; 7 | "nightly") 8 | REPO=nightlies 9 | ;; 10 | *) 11 | echo "invalid ponyc version" 12 | echo "Options:" 13 | echo "release" 14 | echo "nightly" 15 | exit 1 16 | esac 17 | 18 | # 19 | # Libresll is required for ponyup 20 | # 21 | 22 | brew update 23 | brew install libressl 24 | 25 | pushd /tmp || exit 26 | mkdir ponyc 27 | echo ""https://dl.cloudsmith.io/public/ponylang/${REPO}/raw/versions/latest/ponyc-arm64-apple-darwin.tar.gz"" 28 | wget "https://dl.cloudsmith.io/public/ponylang/${REPO}/raw/versions/latest/ponyc-arm64-apple-darwin.tar.gz" -O ponyc.tar.gz 29 | tar xzf ponyc.tar.gz -C ponyc --strip-components=1 30 | popd || exit 31 | 32 | pushd /tmp || exit 33 | mkdir corral 34 | wget "https://dl.cloudsmith.io/public/ponylang/${REPO}/raw/versions/latest/corral-arm64-apple-darwin.tar.gz" -O corral.tar.gz 35 | tar xzf corral.tar.gz -C corral --strip-components=1 36 | popd || exit 37 | -------------------------------------------------------------------------------- /.ci-scripts/macos-x86-install-pony-tools.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | case "${1}" in 4 | "release") 5 | REPO=releases 6 | ;; 7 | "nightly") 8 | REPO=nightlies 9 | ;; 10 | *) 11 | echo "invalid ponyc version" 12 | echo "Options:" 13 | echo "release" 14 | echo "nightly" 15 | exit 1 16 | esac 17 | 18 | # 19 | # Libressl is required for ponyup 20 | # 21 | 22 | brew update 23 | brew install libressl 24 | 25 | # 26 | # Install ponyc the hard way 27 | # It will end up in /tmp/ponyc/ with the binary at /tmp/ponyc/bin/ponyc 28 | # 29 | 30 | pushd /tmp || exit 31 | mkdir ponyc 32 | wget "https://dl.cloudsmith.io/public/ponylang/${REPO}/raw/versions/latest/ponyc-x86-64-apple-darwin.tar.gz" -O ponyc.tar.gz 33 | tar xzf ponyc.tar.gz -C ponyc --strip-components=1 34 | popd || exit 35 | 36 | # 37 | # Install corral the hard way 38 | # It will end up in /tmp/corral/ with the binary at /tmp/corral/bin/corral 39 | # 40 | 41 | pushd /tmp || exit 42 | mkdir corral 43 | wget "https://dl.cloudsmith.io/public/ponylang/${REPO}/raw/versions/latest/corral-x86-64-apple-darwin.tar.gz" -O corral.tar.gz 44 | tar xzf corral.tar.gz -C corral --strip-components=1 45 | popd || exit 46 | -------------------------------------------------------------------------------- /.ci-scripts/release/arm64-apple-darwin-nightly.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # x86-64-unknown-linux release: 4 | # 5 | # - Builds release package 6 | # - Uploads to Cloudsmith 7 | # 8 | # Tools required in the environment that runs this: 9 | # 10 | # - bash 11 | # - cloudsmith-cli 12 | # - GNU coreutils 13 | # - GNU gzip 14 | # - GNU make 15 | # - libressl 16 | # - ponyc 17 | # - corral 18 | # - GNU tar 19 | 20 | # add hard way installed ponyc, corral to our PATH 21 | export PATH="/tmp/corral/bin:/tmp/ponyc/bin/:$PATH" 22 | 23 | set -o errexit 24 | 25 | # Pull in shared configuration specific to this repo 26 | base=$(dirname "$0") 27 | # shellcheck source=.ci-scripts/release/config.bash 28 | source "${base}/config.bash" 29 | 30 | # Verify ENV is set up correctly 31 | # We validate all that need to be set in case, in an absolute emergency, 32 | # we need to run this by hand. Otherwise the GitHub actions environment should 33 | # provide all of these if properly configured 34 | if [[ -z "${CLOUDSMITH_API_KEY}" ]]; then 35 | echo -e "\e[31mCloudsmith API key needs to be set in CLOUDSMITH_API_KEY." 36 | echo -e "Exiting.\e[0m" 37 | exit 1 38 | fi 39 | 40 | if [[ -z "${GITHUB_REPOSITORY}" ]]; then 41 | echo -e "\e[31mName of this repository needs to be set in GITHUB_REPOSITORY." 42 | echo -e "\e[31mShould be in the form OWNER/REPO, for example:" 43 | echo -e "\e[31m ponylang/ponyup" 44 | echo -e "\e[31mExiting.\e[0m" 45 | exit 1 46 | fi 47 | 48 | if [[ -z "${APPLICATION_NAME}" ]]; then 49 | echo -e "\e[31mAPPLICATION_NAME needs to be set." 50 | echo -e "\e[31mExiting.\e[0m" 51 | exit 1 52 | fi 53 | 54 | if [[ -z "${APPLICATION_SUMMARY}" ]]; then 55 | echo -e "\e[31mAPPLICATION_SUMMARY needs to be set." 56 | echo -e "\e[31mIt's a short description of the application that will appear in Cloudsmith." 57 | echo -e "\e[31mExiting.\e[0m" 58 | exit 1 59 | fi 60 | 61 | # no unset variables allowed from here on out 62 | # allow above so we can display nice error messages for expected unset variables 63 | set -o nounset 64 | 65 | TODAY=$(date +%Y%m%d) 66 | 67 | # Compiler target parameters 68 | ARCH=arm64 69 | CPU=apple-m1 70 | 71 | # Triple construction 72 | VENDOR=apple 73 | OS=darwin 74 | TRIPLE=${ARCH}-${VENDOR}-${OS} 75 | 76 | # Build parameters 77 | BUILD_PREFIX=$(mktemp -d) 78 | APPLICATION_VERSION="nightly-${TODAY}" 79 | BUILD_DIR=${BUILD_PREFIX}/${APPLICATION_VERSION} 80 | 81 | # Asset information 82 | PACKAGE_DIR=$(mktemp -d) 83 | PACKAGE=${APPLICATION_NAME}-${TRIPLE} 84 | 85 | # Cloudsmith configuration 86 | CLOUDSMITH_VERSION=${TODAY} 87 | ASSET_OWNER=ponylang 88 | ASSET_REPO=nightlies 89 | ASSET_PATH=${ASSET_OWNER}/${ASSET_REPO} 90 | ASSET_FILE=${PACKAGE_DIR}/${PACKAGE}.tar.gz 91 | ASSET_SUMMARY="${APPLICATION_SUMMARY}" 92 | ASSET_DESCRIPTION="https://github.com/${GITHUB_REPOSITORY}" 93 | 94 | # Build application installation 95 | echo -e "\e[34mBuilding ${APPLICATION_NAME}...\e[0m" 96 | make install prefix="${BUILD_DIR}" arch=${CPU} \ 97 | version="${APPLICATION_VERSION}" 98 | 99 | # Package it all up 100 | echo -e "\e[34mCreating .tar.gz of ${APPLICATION_NAME}...\e[0m" 101 | pushd "${BUILD_PREFIX}" || exit 1 102 | tar -cvzf "${ASSET_FILE}" -- * 103 | popd || exit 1 104 | 105 | # Ship it off to cloudsmith 106 | echo -e "\e[34mUploading package to cloudsmith...\e[0m" 107 | cloudsmith push raw --version "${CLOUDSMITH_VERSION}" \ 108 | --api-key "${CLOUDSMITH_API_KEY}" --summary "${ASSET_SUMMARY}" \ 109 | --description "${ASSET_DESCRIPTION}" ${ASSET_PATH} "${ASSET_FILE}" 110 | -------------------------------------------------------------------------------- /.ci-scripts/release/arm64-apple-darwin-release.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # x86-64-unknown-linux release: 4 | # 5 | # - Builds release package 6 | # - Uploads to Cloudsmith 7 | # 8 | # Tools required in the environment that runs this: 9 | # 10 | # - bash 11 | # - cloudsmith-cli 12 | # - GNU coreutils 13 | # - GNU gzip 14 | # - GNU make 15 | # - libressl 16 | # - ponyc 17 | # - corral 18 | # - GNU tar 19 | 20 | # add hard way installed ponyc, corral to our PATH 21 | export PATH="/tmp/corral/bin:/tmp/ponyc/bin/:$PATH" 22 | 23 | set -o errexit 24 | 25 | # Pull in shared configuration specific to this repo 26 | base=$(dirname "$0") 27 | # shellcheck source=.ci-scripts/release/config.bash 28 | source "${base}/config.bash" 29 | 30 | # Verify ENV is set up correctly 31 | # We validate all that need to be set in case, in an absolute emergency, 32 | # we need to run this by hand. Otherwise the GitHub actions environment should 33 | # provide all of these if properly configured 34 | if [[ -z "${CLOUDSMITH_API_KEY}" ]]; then 35 | echo -e "\e[31mCloudsmith API key needs to be set in CLOUDSMITH_API_KEY." 36 | echo -e "Exiting.\e[0m" 37 | exit 1 38 | fi 39 | 40 | if [[ -z "${GITHUB_REPOSITORY}" ]]; then 41 | echo -e "\e[31mName of this repository needs to be set in GITHUB_REPOSITORY." 42 | echo -e "\e[31mShould be in the form OWNER/REPO, for example:" 43 | echo -e "\e[31m ponylang/ponyup" 44 | echo -e "\e[31mExiting.\e[0m" 45 | exit 1 46 | fi 47 | 48 | if [[ -z "${APPLICATION_NAME}" ]]; then 49 | echo -e "\e[31mAPPLICATION_NAME needs to be set." 50 | echo -e "\e[31mExiting.\e[0m" 51 | exit 1 52 | fi 53 | 54 | if [[ -z "${APPLICATION_SUMMARY}" ]]; then 55 | echo -e "\e[31mAPPLICATION_SUMMARY needs to be set." 56 | echo -e "\e[31mIt's a short description of the application that will appear in Cloudsmith." 57 | echo -e "\e[31mExiting.\e[0m" 58 | exit 1 59 | fi 60 | 61 | # no unset variables allowed from here on out 62 | # allow above so we can display nice error messages for expected unset variables 63 | set -o nounset 64 | 65 | # Compiler target parameters 66 | ARCH=arm64 67 | CPU=apple-m1 68 | 69 | # Triple construction 70 | VENDOR=apple 71 | OS=darwin 72 | TRIPLE=${ARCH}-${VENDOR}-${OS} 73 | 74 | # Build parameters 75 | BUILD_PREFIX=$(mktemp -d) 76 | APPLICATION_VERSION=$(cat VERSION) 77 | BUILD_DIR=${BUILD_PREFIX}/${APPLICATION_VERSION} 78 | 79 | # Asset information 80 | PACKAGE_DIR=$(mktemp -d) 81 | PACKAGE=${APPLICATION_NAME}-${TRIPLE} 82 | 83 | # Cloudsmith configuration 84 | CLOUDSMITH_VERSION=$(cat VERSION) 85 | ASSET_OWNER=ponylang 86 | ASSET_REPO=releases 87 | ASSET_PATH=${ASSET_OWNER}/${ASSET_REPO} 88 | ASSET_FILE=${PACKAGE_DIR}/${PACKAGE}.tar.gz 89 | ASSET_SUMMARY="${APPLICATION_SUMMARY}" 90 | ASSET_DESCRIPTION="https://github.com/${GITHUB_REPOSITORY}" 91 | 92 | # Build application installation 93 | echo -e "\e[34mBuilding ${APPLICATION_NAME}...\e[0m" 94 | make install prefix="${BUILD_DIR}" arch=${CPU} \ 95 | version="${APPLICATION_VERSION}" 96 | 97 | # Package it all up 98 | echo -e "\e[34mCreating .tar.gz of ${APPLICATION_NAME}...\e[0m" 99 | pushd "${BUILD_PREFIX}" || exit 1 100 | tar -cvzf "${ASSET_FILE}" -- * 101 | popd || exit 1 102 | 103 | # Ship it off to cloudsmith 104 | echo -e "\e[34mUploading package to cloudsmith...\e[0m" 105 | cloudsmith push raw --version "${CLOUDSMITH_VERSION}" \ 106 | --api-key "${CLOUDSMITH_API_KEY}" --summary "${ASSET_SUMMARY}" \ 107 | --description "${ASSET_DESCRIPTION}" ${ASSET_PATH} "${ASSET_FILE}" 108 | -------------------------------------------------------------------------------- /.ci-scripts/release/arm64-unknown-linux-nightly.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # x86-64-unknown-linux release: 4 | # 5 | # - Builds release package 6 | # - Uploads to Cloudsmith 7 | # 8 | # Tools required in the environment that runs this: 9 | # 10 | # - bash 11 | # - corral 12 | # - cloudsmith-cli 13 | # - GNU make 14 | # - gzip 15 | # - ponyc (musl based version) 16 | # - tar 17 | 18 | set -o errexit 19 | 20 | # Pull in shared configuration specific to this repo 21 | base=$(dirname "$0") 22 | # shellcheck source=.ci-scripts/release/config.bash 23 | source "${base}/config.bash" 24 | 25 | # Verify ENV is set up correctly 26 | # We validate all that need to be set in case, in an absolute emergency, 27 | # we need to run this by hand. Otherwise the GitHub actions environment should 28 | # provide all of these if properly configured 29 | if [[ -z "${CLOUDSMITH_API_KEY}" ]]; then 30 | echo -e "\e[31mCloudsmith API key needs to be set in CLOUDSMITH_API_KEY." 31 | echo -e "Exiting.\e[0m" 32 | exit 1 33 | fi 34 | 35 | if [[ -z "${GITHUB_REPOSITORY}" ]]; then 36 | echo -e "\e[31mName of this repository needs to be set in GITHUB_REPOSITORY." 37 | echo -e "\e[31mShould be in the form OWNER/REPO, for example:" 38 | echo -e "\e[31m ponylang/ponyup" 39 | echo -e "\e[31mExiting.\e[0m" 40 | exit 1 41 | fi 42 | 43 | if [[ -z "${APPLICATION_NAME}" ]]; then 44 | echo -e "\e[31mAPPLICATION_NAME needs to be set." 45 | echo -e "\e[31mExiting.\e[0m" 46 | exit 1 47 | fi 48 | 49 | if [[ -z "${APPLICATION_SUMMARY}" ]]; then 50 | echo -e "\e[31mAPPLICATION_SUMMARY needs to be set." 51 | echo -e "\e[31mIt's a short description of the application that will appear in Cloudsmith." 52 | echo -e "\e[31mExiting.\e[0m" 53 | exit 1 54 | fi 55 | 56 | # no unset variables allowed from here on out 57 | # allow above so we can display nice error messages for expected unset variables 58 | set -o nounset 59 | 60 | TODAY=$(date +%Y%m%d) 61 | 62 | # Compiler target parameters 63 | ARCH=arm64 64 | CPU=generic 65 | 66 | # Triple construction 67 | VENDOR=unknown 68 | OS=linux 69 | TRIPLE=${ARCH}-${VENDOR}-${OS} 70 | 71 | # Build parameters 72 | BUILD_PREFIX=$(mktemp -d) 73 | APPLICATION_VERSION="nightly-${TODAY}" 74 | BUILD_DIR=${BUILD_PREFIX}/${APPLICATION_VERSION} 75 | 76 | # Asset information 77 | PACKAGE_DIR=$(mktemp -d) 78 | PACKAGE=${APPLICATION_NAME}-${TRIPLE} 79 | 80 | # Cloudsmith configuration 81 | CLOUDSMITH_VERSION=${TODAY} 82 | ASSET_OWNER=ponylang 83 | ASSET_REPO=nightlies 84 | ASSET_PATH=${ASSET_OWNER}/${ASSET_REPO} 85 | ASSET_FILE=${PACKAGE_DIR}/${PACKAGE}.tar.gz 86 | ASSET_SUMMARY="${APPLICATION_SUMMARY}" 87 | ASSET_DESCRIPTION="https://github.com/${GITHUB_REPOSITORY}" 88 | 89 | # Build application installation 90 | echo -e "\e[34mBuilding ${APPLICATION_NAME}...\e[0m" 91 | make install prefix="${BUILD_DIR}" arch=${CPU} \ 92 | version="${APPLICATION_VERSION}" static=true linker=bfd 93 | 94 | # Package it all up 95 | echo -e "\e[34mCreating .tar.gz of ${APPLICATION_NAME}...\e[0m" 96 | pushd "${BUILD_PREFIX}" || exit 1 97 | tar -cvzf "${ASSET_FILE}" -- * 98 | popd || exit 1 99 | 100 | # Ship it off to cloudsmith 101 | echo -e "\e[34mUploading package to cloudsmith...\e[0m" 102 | cloudsmith push raw --version "${CLOUDSMITH_VERSION}" \ 103 | --api-key "${CLOUDSMITH_API_KEY}" --summary "${ASSET_SUMMARY}" \ 104 | --description "${ASSET_DESCRIPTION}" ${ASSET_PATH} "${ASSET_FILE}" 105 | -------------------------------------------------------------------------------- /.ci-scripts/release/arm64-unknown-linux-release.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # x86-64-unknown-linux release: 4 | # 5 | # - Builds release package 6 | # - Uploads to Cloudsmith 7 | # 8 | # Tools required in the environment that runs this: 9 | # 10 | # - bash 11 | # - corral 12 | # - cloudsmith-cli 13 | # - GNU make 14 | # - gzip 15 | # - ponyc (musl based version) 16 | # - tar 17 | 18 | set -o errexit 19 | 20 | # Pull in shared configuration specific to this repo 21 | base=$(dirname "$0") 22 | # shellcheck source=.ci-scripts/release/config.bash 23 | source "${base}/config.bash" 24 | 25 | # Verify ENV is set up correctly 26 | # We validate all that need to be set in case, in an absolute emergency, 27 | # we need to run this by hand. Otherwise the GitHub actions environment should 28 | # provide all of these if properly configured 29 | if [[ -z "${CLOUDSMITH_API_KEY}" ]]; then 30 | echo -e "\e[31mCloudsmith API key needs to be set in CLOUDSMITH_API_KEY." 31 | echo -e "Exiting.\e[0m" 32 | exit 1 33 | fi 34 | 35 | if [[ -z "${GITHUB_REPOSITORY}" ]]; then 36 | echo -e "\e[31mName of this repository needs to be set in GITHUB_REPOSITORY." 37 | echo -e "\e[31mShould be in the form OWNER/REPO, for example:" 38 | echo -e "\e[31m ponylang/ponyup" 39 | echo -e "\e[31mExiting.\e[0m" 40 | exit 1 41 | fi 42 | 43 | if [[ -z "${APPLICATION_NAME}" ]]; then 44 | echo -e "\e[31mAPPLICATION_NAME needs to be set." 45 | echo -e "\e[31mExiting.\e[0m" 46 | exit 1 47 | fi 48 | 49 | if [[ -z "${APPLICATION_SUMMARY}" ]]; then 50 | echo -e "\e[31mAPPLICATION_SUMMARY needs to be set." 51 | echo -e "\e[31mIt's a short description of the application that will appear in Cloudsmith." 52 | echo -e "\e[31mExiting.\e[0m" 53 | exit 1 54 | fi 55 | 56 | # no unset variables allowed from here on out 57 | # allow above so we can display nice error messages for expected unset variables 58 | set -o nounset 59 | 60 | # Compiler target parameters 61 | ARCH=arm64 62 | CPU=generic 63 | 64 | # Triple construction 65 | VENDOR=unknown 66 | OS=linux 67 | TRIPLE=${ARCH}-${VENDOR}-${OS} 68 | 69 | # Build parameters 70 | BUILD_PREFIX=$(mktemp -d) 71 | APPLICATION_VERSION=$(cat VERSION) 72 | BUILD_DIR=${BUILD_PREFIX}/${APPLICATION_VERSION} 73 | 74 | # Asset information 75 | PACKAGE_DIR=$(mktemp -d) 76 | PACKAGE=${APPLICATION_NAME}-${TRIPLE} 77 | 78 | # Cloudsmith configuration 79 | CLOUDSMITH_VERSION=$(cat VERSION) 80 | ASSET_OWNER=ponylang 81 | ASSET_REPO=releases 82 | ASSET_PATH=${ASSET_OWNER}/${ASSET_REPO} 83 | ASSET_FILE=${PACKAGE_DIR}/${PACKAGE}.tar.gz 84 | ASSET_SUMMARY="${APPLICATION_SUMMARY}" 85 | ASSET_DESCRIPTION="https://github.com/${GITHUB_REPOSITORY}" 86 | 87 | # Build application installation 88 | echo -e "\e[34mBuilding ${APPLICATION_NAME}...\e[0m" 89 | make install prefix="${BUILD_DIR}" arch=${CPU} \ 90 | version="${APPLICATION_VERSION}" static=true linker=bfd 91 | 92 | # Package it all up 93 | echo -e "\e[34mCreating .tar.gz of ${APPLICATION_NAME}...\e[0m" 94 | pushd "${BUILD_PREFIX}" || exit 1 95 | tar -cvzf "${ASSET_FILE}" -- * 96 | popd || exit 1 97 | 98 | # Ship it off to cloudsmith 99 | echo -e "\e[34mUploading package to cloudsmith...\e[0m" 100 | cloudsmith push raw --version "${CLOUDSMITH_VERSION}" \ 101 | --api-key "${CLOUDSMITH_API_KEY}" --summary "${ASSET_SUMMARY}" \ 102 | --description "${ASSET_DESCRIPTION}" ${ASSET_PATH} "${ASSET_FILE}" 103 | -------------------------------------------------------------------------------- /.ci-scripts/release/build-docker-images-on-release.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # *** You should already be logged in to GitHub Container Registry when you run # this *** 4 | # 5 | # Builds docker release images with two tags: 6 | # 7 | # - release 8 | # - X.Y.Z for example 0.32.1 9 | # 10 | # Tools required in the environment that runs this: 11 | # 12 | # - bash 13 | # - docker 14 | 15 | set -o errexit 16 | 17 | # Pull in shared configuration specific to this repo 18 | base=$(dirname "$0") 19 | # shellcheck source=.ci-scripts/release/config.bash 20 | source "${base}/config.bash" 21 | 22 | # Verify ENV is set up correctly 23 | # We validate all that need to be set in case, in an absolute emergency, 24 | # we need to run this by hand. Otherwise the GitHub actions environment should 25 | # provide all of these if properly configured 26 | if [[ -z "${GITHUB_REF}" ]]; then 27 | echo -e "\e[31mThe release tag needs to be set in GITHUB_REF." 28 | echo -e "\e[31mThe tag should be in the following GitHub specific form:" 29 | echo -e "\e[31m /refs/tags/X.Y.Z" 30 | echo -e "\e[31mwhere X.Y.Z is the version we are releasing" 31 | echo -e "\e[31mExiting.\e[0m" 32 | exit 1 33 | fi 34 | 35 | if [[ -z "${GITHUB_REPOSITORY}" ]]; then 36 | echo -e "\e[31mName of this repository needs to be set in GITHUB_REPOSITORY." 37 | echo -e "\e[31mShould be in the form OWNER/REPO, for example:" 38 | echo -e "\e[31m ponylang/ponyup" 39 | echo -e "\e[31mThis will be used as the docker image name." 40 | echo -e "\e[31mExiting.\e[0m" 41 | exit 1 42 | fi 43 | 44 | # no unset variables allowed from here on out 45 | # allow above so we can display nice error messages for expected unset variables 46 | set -o nounset 47 | 48 | # We aren't validating TAG is in our x.y.z format but we could. 49 | # For now, TAG validating is left up to the configuration in 50 | # our GitHub workflow 51 | # Tag ref version: "refs/tags/1.0.0" 52 | # Version: "1.0.0" 53 | VERSION="${GITHUB_REF/refs\/tags\//}" 54 | 55 | ## GitHub Container Registry 56 | NAME="ghcr.io/${GITHUB_REPOSITORY}" 57 | # Build and push :VERSION tag e.g. ghcr.io/ponylang/ponyup:0.32.1 58 | DOCKER_TAG="${NAME}:${VERSION}" 59 | docker build --pull -t "${DOCKER_TAG}" . 60 | docker push "${DOCKER_TAG}" 61 | 62 | # Build and push "release" tag e.g. ghcr.io/ponylang/ponyup:release 63 | DOCKER_TAG="${NAME}:release" 64 | docker build --pull -t "${DOCKER_TAG}" . 65 | docker push "${DOCKER_TAG}" 66 | -------------------------------------------------------------------------------- /.ci-scripts/release/build-latest-docker-images.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # *** You should already be logged in to GitHub Container Registry when you run 4 | # this *** 5 | # 6 | # Builds docker latest docker images. 7 | # 8 | # Tools required in the environment that runs this: 9 | # 10 | # - bash 11 | # - docker 12 | 13 | set -o errexit 14 | 15 | # Pull in shared configuration specific to this repo 16 | base=$(dirname "$0") 17 | # shellcheck source=.ci-scripts/release/config.bash 18 | source "${base}/config.bash" 19 | 20 | # Verify ENV is set up correctly 21 | # We validate all that need to be set in case, in an absolute emergency, 22 | # we need to run this by hand. Otherwise the GitHub actions environment should 23 | # provide all of these if properly configured 24 | if [[ -z "${GITHUB_REPOSITORY}" ]]; then 25 | echo -e "\e[31mName of this repository needs to be set in GITHUB_REPOSITORY." 26 | echo -e "\e[31mShould be in the form OWNER/REPO, for example:" 27 | echo -e "\e[31m ponylang/ponyup" 28 | echo -e "\e[31mThis will be used as the docker image name." 29 | echo -e "\e[31mExiting.\e[0m" 30 | exit 1 31 | fi 32 | 33 | # no unset variables allowed from here on out 34 | # allow above so we can display nice error messages for expected unset variables 35 | set -o nounset 36 | 37 | ## GitHub Container Registry 38 | 39 | NAME="ghcr.io/${GITHUB_REPOSITORY}" 40 | # Build and push "latest" tag e.g. ghcr.io/ponylang/ponyup:latest 41 | DOCKER_TAG="${NAME}:latest" 42 | docker build --pull -t "${DOCKER_TAG}" . 43 | docker push "${DOCKER_TAG}" 44 | -------------------------------------------------------------------------------- /.ci-scripts/release/config.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export APPLICATION_NAME="ponyup" 4 | export APPLICATION_SUMMARY="The Pony toolchain multiplexer" 5 | -------------------------------------------------------------------------------- /.ci-scripts/release/x86-64-apple-darwin-nightly.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # - Builds release package 4 | # - Uploads to Cloudsmith 5 | # 6 | # Tools required in the environment that runs this: 7 | # 8 | # - bash 9 | # - cloudsmith-cli 10 | # - GNU coreutils 11 | # - GNU gzip 12 | # - GNU make 13 | # - libressl 14 | # - ponyc 15 | # - corral 16 | # - GNU tar 17 | 18 | # add hard way installed ponyc, corral to our PATH 19 | export PATH="/tmp/corral/bin:/tmp/ponyc/bin/:/Library/Frameworks/Python.framework/Versions/3.11/bin/:$PATH" 20 | set -o errexit 21 | 22 | # Pull in shared configuration specific to this repo 23 | base=$(dirname "$0") 24 | # shellcheck source=.ci-scripts/release/config.bash 25 | source "${base}/config.bash" 26 | 27 | # Verify ENV is set up correctly 28 | # We validate all that need to be set in case, in an absolute emergency, 29 | # we need to run this by hand. Otherwise the GitHub actions environment should 30 | # provide all of these if properly configured 31 | if [[ -z "${CLOUDSMITH_API_KEY}" ]]; then 32 | echo -e "\e[31mCloudsmith API key needs to be set in CLOUDSMITH_API_KEY." 33 | echo -e "Exiting.\e[0m" 34 | exit 1 35 | fi 36 | 37 | if [[ -z "${GITHUB_REPOSITORY}" ]]; then 38 | echo -e "\e[31mName of this repository needs to be set in GITHUB_REPOSITORY." 39 | echo -e "\e[31mShould be in the form OWNER/REPO, for example:" 40 | echo -e "\e[31m ponylang/ponyup" 41 | echo -e "\e[31mExiting.\e[0m" 42 | exit 1 43 | fi 44 | 45 | if [[ -z "${APPLICATION_NAME}" ]]; then 46 | echo -e "\e[31mAPPLICATION_NAME needs to be set." 47 | echo -e "\e[31mExiting.\e[0m" 48 | exit 1 49 | fi 50 | 51 | if [[ -z "${APPLICATION_SUMMARY}" ]]; then 52 | echo -e "\e[31mAPPLICATION_SUMMARY needs to be set." 53 | echo -e "\e[31mIt's a short description of the application that will appear in Cloudsmith." 54 | echo -e "\e[31mExiting.\e[0m" 55 | exit 1 56 | fi 57 | 58 | # no unset variables allowed from here on out 59 | # allow above so we can display nice error messages for expected unset variables 60 | set -o nounset 61 | 62 | TODAY=$(date +%Y%m%d) 63 | 64 | # Compiler target parameters 65 | ARCH=x86-64 66 | 67 | # Triple construction 68 | VENDOR=apple 69 | OS=darwin 70 | TRIPLE=${ARCH}-${VENDOR}-${OS} 71 | 72 | # Build parameters 73 | BUILD_PREFIX=$(mktemp -d) 74 | APPLICATION_VERSION="nightly-${TODAY}" 75 | BUILD_DIR=${BUILD_PREFIX}/${APPLICATION_VERSION} 76 | 77 | # Asset information 78 | PACKAGE_DIR=$(mktemp -d) 79 | PACKAGE=${APPLICATION_NAME}-${TRIPLE} 80 | 81 | # Cloudsmith configuration 82 | CLOUDSMITH_VERSION=${TODAY} 83 | ASSET_OWNER=ponylang 84 | ASSET_REPO=nightlies 85 | ASSET_PATH=${ASSET_OWNER}/${ASSET_REPO} 86 | ASSET_FILE=${PACKAGE_DIR}/${PACKAGE}.tar.gz 87 | ASSET_SUMMARY="${APPLICATION_SUMMARY}" 88 | ASSET_DESCRIPTION="https://github.com/${GITHUB_REPOSITORY}" 89 | 90 | # Build application installation 91 | echo -e "\e[34mBuilding ${APPLICATION_NAME}...\e[0m" 92 | make install prefix="${BUILD_DIR}" arch=${ARCH} \ 93 | version="${APPLICATION_VERSION}" 94 | 95 | # Package it all up 96 | echo -e "\e[34mCreating .tar.gz of ${APPLICATION_NAME}...\e[0m" 97 | pushd "${BUILD_PREFIX}" || exit 1 98 | tar -cvzf "${ASSET_FILE}" -- * 99 | popd || exit 1 100 | 101 | # Ship it off to cloudsmith 102 | echo -e "\e[34mUploading package to cloudsmith...\e[0m" 103 | cloudsmith push raw --version "${CLOUDSMITH_VERSION}" \ 104 | --api-key "${CLOUDSMITH_API_KEY}" --summary "${ASSET_SUMMARY}" \ 105 | --description "${ASSET_DESCRIPTION}" ${ASSET_PATH} "${ASSET_FILE}" 106 | -------------------------------------------------------------------------------- /.ci-scripts/release/x86-64-apple-darwin-release.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # - Builds release package 4 | # - Uploads to Cloudsmith 5 | # 6 | # Tools required in the environment that runs this: 7 | # 8 | # - bash 9 | # - cloudsmith-cli 10 | # - GNU coreutils 11 | # - GNU gzip 12 | # - GNU make 13 | # - libressl 14 | # - ponyc 15 | # - corral 16 | # - GNU tar 17 | 18 | # add hard way installed ponyc, corral to our PATH 19 | export PATH="/tmp/corral/bin:/tmp/ponyc/bin/:/Library/Frameworks/Python.framework/Versions/3.11/bin/:$PATH" 20 | set -o errexit 21 | 22 | # Pull in shared configuration specific to this repo 23 | base=$(dirname "$0") 24 | # shellcheck source=.ci-scripts/release/config.bash 25 | source "${base}/config.bash" 26 | 27 | # Verify ENV is set up correctly 28 | # We validate all that need to be set in case, in an absolute emergency, 29 | # we need to run this by hand. Otherwise the GitHub actions environment should 30 | # provide all of these if properly configured 31 | if [[ -z "${CLOUDSMITH_API_KEY}" ]]; then 32 | echo -e "\e[31mCloudsmith API key needs to be set in CLOUDSMITH_API_KEY." 33 | echo -e "Exiting.\e[0m" 34 | exit 1 35 | fi 36 | 37 | if [[ -z "${GITHUB_REPOSITORY}" ]]; then 38 | echo -e "\e[31mName of this repository needs to be set in GITHUB_REPOSITORY." 39 | echo -e "\e[31mShould be in the form OWNER/REPO, for example:" 40 | echo -e "\e[31m ponylang/ponyup" 41 | echo -e "\e[31mExiting.\e[0m" 42 | exit 1 43 | fi 44 | 45 | if [[ -z "${APPLICATION_NAME}" ]]; then 46 | echo -e "\e[31mAPPLICATION_NAME needs to be set." 47 | echo -e "\e[31mExiting.\e[0m" 48 | exit 1 49 | fi 50 | 51 | if [[ -z "${APPLICATION_SUMMARY}" ]]; then 52 | echo -e "\e[31mAPPLICATION_SUMMARY needs to be set." 53 | echo -e "\e[31mIt's a short description of the application that will appear in Cloudsmith." 54 | echo -e "\e[31mExiting.\e[0m" 55 | exit 1 56 | fi 57 | 58 | # no unset variables allowed from here on out 59 | # allow above so we can display nice error messages for expected unset variables 60 | set -o nounset 61 | 62 | # Compiler target parameters 63 | ARCH=x86-64 64 | 65 | # Triple construction 66 | VENDOR=apple 67 | OS=darwin 68 | TRIPLE=${ARCH}-${VENDOR}-${OS} 69 | 70 | # Build parameters 71 | BUILD_PREFIX=$(mktemp -d) 72 | APPLICATION_VERSION=$(cat VERSION) 73 | BUILD_DIR=${BUILD_PREFIX}/${APPLICATION_VERSION} 74 | 75 | # Asset information 76 | PACKAGE_DIR=$(mktemp -d) 77 | PACKAGE=${APPLICATION_NAME}-${TRIPLE} 78 | 79 | # Cloudsmith configuration 80 | CLOUDSMITH_VERSION=$(cat VERSION) 81 | ASSET_OWNER=ponylang 82 | ASSET_REPO=releases 83 | ASSET_PATH=${ASSET_OWNER}/${ASSET_REPO} 84 | ASSET_FILE=${PACKAGE_DIR}/${PACKAGE}.tar.gz 85 | ASSET_SUMMARY="${APPLICATION_SUMMARY}" 86 | ASSET_DESCRIPTION="https://github.com/${GITHUB_REPOSITORY}" 87 | 88 | # Build application installation 89 | echo -e "\e[34mBuilding ${APPLICATION_NAME}...\e[0m" 90 | make install prefix="${BUILD_DIR}" arch=${ARCH} \ 91 | version="${APPLICATION_VERSION}" 92 | 93 | # Package it all up 94 | echo -e "\e[34mCreating .tar.gz of ${APPLICATION_NAME}...\e[0m" 95 | pushd "${BUILD_PREFIX}" || exit 1 96 | tar -cvzf "${ASSET_FILE}" -- * 97 | popd || exit 1 98 | 99 | # Ship it off to cloudsmith 100 | echo -e "\e[34mUploading package to cloudsmith...\e[0m" 101 | cloudsmith push raw --version "${CLOUDSMITH_VERSION}" \ 102 | --api-key "${CLOUDSMITH_API_KEY}" --summary "${ASSET_SUMMARY}" \ 103 | --description "${ASSET_DESCRIPTION}" ${ASSET_PATH} "${ASSET_FILE}" 104 | -------------------------------------------------------------------------------- /.ci-scripts/release/x86-64-unknown-linux-nightly.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # x86-64-unknown-linux release: 4 | # 5 | # - Builds release package 6 | # - Uploads to Cloudsmith 7 | # 8 | # Tools required in the environment that runs this: 9 | # 10 | # - bash 11 | # - corral 12 | # - cloudsmith-cli 13 | # - GNU make 14 | # - gzip 15 | # - ponyc (musl based version) 16 | # - tar 17 | 18 | set -o errexit 19 | 20 | # Pull in shared configuration specific to this repo 21 | base=$(dirname "$0") 22 | # shellcheck source=.ci-scripts/release/config.bash 23 | source "${base}/config.bash" 24 | 25 | # Verify ENV is set up correctly 26 | # We validate all that need to be set in case, in an absolute emergency, 27 | # we need to run this by hand. Otherwise the GitHub actions environment should 28 | # provide all of these if properly configured 29 | if [[ -z "${CLOUDSMITH_API_KEY}" ]]; then 30 | echo -e "\e[31mCloudsmith API key needs to be set in CLOUDSMITH_API_KEY." 31 | echo -e "Exiting.\e[0m" 32 | exit 1 33 | fi 34 | 35 | if [[ -z "${GITHUB_REPOSITORY}" ]]; then 36 | echo -e "\e[31mName of this repository needs to be set in GITHUB_REPOSITORY." 37 | echo -e "\e[31mShould be in the form OWNER/REPO, for example:" 38 | echo -e "\e[31m ponylang/ponyup" 39 | echo -e "\e[31mExiting.\e[0m" 40 | exit 1 41 | fi 42 | 43 | if [[ -z "${APPLICATION_NAME}" ]]; then 44 | echo -e "\e[31mAPPLICATION_NAME needs to be set." 45 | echo -e "\e[31mExiting.\e[0m" 46 | exit 1 47 | fi 48 | 49 | if [[ -z "${APPLICATION_SUMMARY}" ]]; then 50 | echo -e "\e[31mAPPLICATION_SUMMARY needs to be set." 51 | echo -e "\e[31mIt's a short description of the application that will appear in Cloudsmith." 52 | echo -e "\e[31mExiting.\e[0m" 53 | exit 1 54 | fi 55 | 56 | # no unset variables allowed from here on out 57 | # allow above so we can display nice error messages for expected unset variables 58 | set -o nounset 59 | 60 | TODAY=$(date +%Y%m%d) 61 | 62 | # Compiler target parameters 63 | ARCH=x86-64 64 | 65 | # Triple construction 66 | VENDOR=unknown 67 | OS=linux 68 | TRIPLE=${ARCH}-${VENDOR}-${OS} 69 | 70 | # Build parameters 71 | BUILD_PREFIX=$(mktemp -d) 72 | APPLICATION_VERSION="nightly-${TODAY}" 73 | BUILD_DIR=${BUILD_PREFIX}/${APPLICATION_VERSION} 74 | 75 | # Asset information 76 | PACKAGE_DIR=$(mktemp -d) 77 | PACKAGE=${APPLICATION_NAME}-${TRIPLE} 78 | 79 | # Cloudsmith configuration 80 | CLOUDSMITH_VERSION=${TODAY} 81 | ASSET_OWNER=ponylang 82 | ASSET_REPO=nightlies 83 | ASSET_PATH=${ASSET_OWNER}/${ASSET_REPO} 84 | ASSET_FILE=${PACKAGE_DIR}/${PACKAGE}.tar.gz 85 | ASSET_SUMMARY="${APPLICATION_SUMMARY}" 86 | ASSET_DESCRIPTION="https://github.com/${GITHUB_REPOSITORY}" 87 | 88 | # Build application installation 89 | echo -e "\e[34mBuilding ${APPLICATION_NAME}...\e[0m" 90 | make install prefix="${BUILD_DIR}" arch=${ARCH} \ 91 | version="${APPLICATION_VERSION}" static=true linker=bfd 92 | 93 | # Package it all up 94 | echo -e "\e[34mCreating .tar.gz of ${APPLICATION_NAME}...\e[0m" 95 | pushd "${BUILD_PREFIX}" || exit 1 96 | tar -cvzf "${ASSET_FILE}" -- * 97 | popd || exit 1 98 | 99 | # Ship it off to cloudsmith 100 | echo -e "\e[34mUploading package to cloudsmith...\e[0m" 101 | cloudsmith push raw --version "${CLOUDSMITH_VERSION}" \ 102 | --api-key "${CLOUDSMITH_API_KEY}" --summary "${ASSET_SUMMARY}" \ 103 | --description "${ASSET_DESCRIPTION}" ${ASSET_PATH} "${ASSET_FILE}" 104 | -------------------------------------------------------------------------------- /.ci-scripts/release/x86-64-unknown-linux-release.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # x86-64-unknown-linux release: 4 | # 5 | # - Builds release package 6 | # - Uploads to Cloudsmith 7 | # 8 | # Tools required in the environment that runs this: 9 | # 10 | # - bash 11 | # - corral 12 | # - cloudsmith-cli 13 | # - GNU make 14 | # - gzip 15 | # - ponyc (musl based version) 16 | # - tar 17 | 18 | set -o errexit 19 | 20 | # Pull in shared configuration specific to this repo 21 | base=$(dirname "$0") 22 | # shellcheck source=.ci-scripts/release/config.bash 23 | source "${base}/config.bash" 24 | 25 | # Verify ENV is set up correctly 26 | # We validate all that need to be set in case, in an absolute emergency, 27 | # we need to run this by hand. Otherwise the GitHub actions environment should 28 | # provide all of these if properly configured 29 | if [[ -z "${CLOUDSMITH_API_KEY}" ]]; then 30 | echo -e "\e[31mCloudsmith API key needs to be set in CLOUDSMITH_API_KEY." 31 | echo -e "Exiting.\e[0m" 32 | exit 1 33 | fi 34 | 35 | if [[ -z "${GITHUB_REPOSITORY}" ]]; then 36 | echo -e "\e[31mName of this repository needs to be set in GITHUB_REPOSITORY." 37 | echo -e "\e[31mShould be in the form OWNER/REPO, for example:" 38 | echo -e "\e[31m ponylang/ponyup" 39 | echo -e "\e[31mExiting.\e[0m" 40 | exit 1 41 | fi 42 | 43 | if [[ -z "${APPLICATION_NAME}" ]]; then 44 | echo -e "\e[31mAPPLICATION_NAME needs to be set." 45 | echo -e "\e[31mExiting.\e[0m" 46 | exit 1 47 | fi 48 | 49 | if [[ -z "${APPLICATION_SUMMARY}" ]]; then 50 | echo -e "\e[31mAPPLICATION_SUMMARY needs to be set." 51 | echo -e "\e[31mIt's a short description of the application that will appear in Cloudsmith." 52 | echo -e "\e[31mExiting.\e[0m" 53 | exit 1 54 | fi 55 | 56 | # no unset variables allowed from here on out 57 | # allow above so we can display nice error messages for expected unset variables 58 | set -o nounset 59 | 60 | # Compiler target parameters 61 | ARCH=x86-64 62 | 63 | # Triple construction 64 | VENDOR=unknown 65 | OS=linux 66 | TRIPLE=${ARCH}-${VENDOR}-${OS} 67 | 68 | # Build parameters 69 | BUILD_PREFIX=$(mktemp -d) 70 | APPLICATION_VERSION=$(cat VERSION) 71 | BUILD_DIR=${BUILD_PREFIX}/${APPLICATION_VERSION} 72 | 73 | # Asset information 74 | PACKAGE_DIR=$(mktemp -d) 75 | PACKAGE=${APPLICATION_NAME}-${TRIPLE} 76 | 77 | # Cloudsmith configuration 78 | CLOUDSMITH_VERSION=$(cat VERSION) 79 | ASSET_OWNER=ponylang 80 | ASSET_REPO=releases 81 | ASSET_PATH=${ASSET_OWNER}/${ASSET_REPO} 82 | ASSET_FILE=${PACKAGE_DIR}/${PACKAGE}.tar.gz 83 | ASSET_SUMMARY="${APPLICATION_SUMMARY}" 84 | ASSET_DESCRIPTION="https://github.com/${GITHUB_REPOSITORY}" 85 | 86 | # Build application installation 87 | echo -e "\e[34mBuilding ${APPLICATION_NAME}...\e[0m" 88 | make install prefix="${BUILD_DIR}" arch=${ARCH} \ 89 | version="${APPLICATION_VERSION}" static=true linker=bfd 90 | 91 | # Package it all up 92 | echo -e "\e[34mCreating .tar.gz of ${APPLICATION_NAME}...\e[0m" 93 | pushd "${BUILD_PREFIX}" || exit 1 94 | tar -cvzf "${ASSET_FILE}" -- * 95 | popd || exit 1 96 | 97 | # Ship it off to cloudsmith 98 | echo -e "\e[34mUploading package to cloudsmith...\e[0m" 99 | cloudsmith push raw --version "${CLOUDSMITH_VERSION}" \ 100 | --api-key "${CLOUDSMITH_API_KEY}" --summary "${ASSET_SUMMARY}" \ 101 | --description "${ASSET_DESCRIPTION}" ${ASSET_PATH} "${ASSET_FILE}" 102 | -------------------------------------------------------------------------------- /.ci-scripts/test-bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./ponyup-init.sh --repository=nightlies 4 | 5 | MAKE=${MAKE:=make} 6 | SSL=${SSL:=1.1.x} 7 | 8 | export PATH=$HOME/.local/share/ponyup/bin:$PATH 9 | 10 | if [ -n "${PLATFORM}" ]; then 11 | ponyup default "${PLATFORM}" 12 | fi 13 | 14 | ponyup update ponyc nightly 15 | ponyup update corral nightly 16 | 17 | ${MAKE} clean 18 | ${MAKE} ssl=${SSL} 19 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | open_collective: ponyc 2 | -------------------------------------------------------------------------------- /.github/linters/.markdown-lint.yml: -------------------------------------------------------------------------------- 1 | { 2 | "MD013": false 3 | } 4 | -------------------------------------------------------------------------------- /.github/workflows/add-discuss-during-sync.yml: -------------------------------------------------------------------------------- 1 | name: Add discuss during sync label 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | - reopened 8 | issue_comment: 9 | types: 10 | - created 11 | pull_request_target: 12 | types: 13 | - opened 14 | - edited 15 | - ready_for_review 16 | - reopened 17 | pull_request_review: 18 | types: 19 | - submitted 20 | 21 | permissions: 22 | pull-requests: write 23 | 24 | jobs: 25 | add-label: 26 | runs-on: ubuntu-latest 27 | steps: 28 | - name: Add "discuss during sync" label to active GH entity 29 | uses: andymckay/labeler@467347716a3bdbca7f277cb6cd5fa9c5205c5412 30 | with: 31 | repo-token: ${{ secrets.PONYLANG_MAIN_API_TOKEN }} 32 | add-labels: "discuss during sync" 33 | -------------------------------------------------------------------------------- /.github/workflows/announce-a-release.yml: -------------------------------------------------------------------------------- 1 | name: Announce a release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'announce-[0-9]+.[0-9]+.[0-9]+' 7 | 8 | concurrency: announce-a-release 9 | 10 | permissions: 11 | packages: read 12 | contents: write 13 | 14 | jobs: 15 | announce: 16 | name: Announcements 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Checkout main 20 | uses: actions/checkout@v4.1.1 21 | with: 22 | ref: "main" 23 | token: ${{ secrets.RELEASE_TOKEN }} 24 | - name: Release notes 25 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 26 | with: 27 | entrypoint: publish-release-notes-to-github 28 | env: 29 | RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} 30 | - name: Zulip 31 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 32 | with: 33 | entrypoint: send-announcement-to-pony-zulip 34 | env: 35 | ZULIP_API_KEY: ${{ secrets.ZULIP_RELEASE_API_KEY }} 36 | ZULIP_EMAIL: ${{ secrets.ZULIP_RELEASE_EMAIL }} 37 | - name: Last Week in Pony 38 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 39 | with: 40 | entrypoint: add-announcement-to-last-week-in-pony 41 | env: 42 | RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} 43 | 44 | post-announcement: 45 | name: Tasks to run after the release has been announced 46 | needs: 47 | - announce 48 | runs-on: ubuntu-latest 49 | steps: 50 | - name: Checkout main 51 | uses: actions/checkout@v4.1.1 52 | with: 53 | ref: "main" 54 | token: ${{ secrets.RELEASE_TOKEN }} 55 | - name: Rotate release notes 56 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 57 | with: 58 | entrypoint: rotate-release-notes 59 | env: 60 | GIT_USER_NAME: "Ponylang Main Bot" 61 | GIT_USER_EMAIL: "ponylang.main@gmail.com" 62 | - name: Delete announcement trigger tag 63 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 64 | with: 65 | entrypoint: delete-announcement-tag 66 | env: 67 | GIT_USER_NAME: "Ponylang Main Bot" 68 | GIT_USER_EMAIL: "ponylang.main@gmail.com" 69 | -------------------------------------------------------------------------------- /.github/workflows/breakage-against-linux-ponyc-latest.yml: -------------------------------------------------------------------------------- 1 | name: Linux ponyc update breakage test 2 | 3 | on: 4 | repository_dispatch: 5 | types: [shared-docker-linux-builders-updated] 6 | 7 | permissions: 8 | packages: read 9 | 10 | jobs: 11 | vs-ponyc-main-linux: 12 | name: Verify main against ponyc main on Linux 13 | runs-on: ubuntu-latest 14 | container: 15 | image: ghcr.io/ponylang/shared-docker-ci-x86-64-unknown-linux-builder-with-libressl-4.0.0:latest 16 | steps: 17 | - uses: actions/checkout@v4.1.1 18 | - name: Test with a recent ponyc from main 19 | run: make test config=debug 20 | - name: Send alert on failure 21 | if: ${{ failure() }} 22 | uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 23 | with: 24 | api-key: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_API_KEY }} 25 | email: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_EMAIL }} 26 | organization-url: 'https://ponylang.zulipchat.com/' 27 | to: notifications 28 | type: stream 29 | topic: ${{ github.repository }} scheduled job failure 30 | content: ${{ github.server_url}}/${{ github.repository }}/actions/runs/${{ github.run_id }} failed. 31 | -------------------------------------------------------------------------------- /.github/workflows/breakage-against-macos-arm64-ponyc-latest.yml: -------------------------------------------------------------------------------- 1 | name: arm64 macOS ponyc update breakage test 2 | 3 | on: 4 | repository_dispatch: 5 | types: [ponyc-arm64-macos-nightly-released] 6 | 7 | permissions: 8 | packages: read 9 | 10 | jobs: 11 | vs-ponyc-main-macos: 12 | name: Verify main against ponyc main on arm64 macOS 13 | runs-on: macos-15 14 | steps: 15 | - uses: actions/checkout@v4.1.1 16 | - name: install pony tools 17 | run: bash .ci-scripts/macos-arm64-install-pony-tools.bash nightly 18 | - name: Test with the most recent ponyc release 19 | run: | 20 | export PATH=/tmp/corral/bin/:/tmp/ponyc/bin/:$PATH 21 | make test 22 | - name: Send alert on failure 23 | if: ${{ failure() }} 24 | uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 25 | with: 26 | api-key: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_API_KEY }} 27 | email: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_EMAIL }} 28 | organization-url: 'https://ponylang.zulipchat.com/' 29 | to: notifications 30 | type: stream 31 | topic: ${{ github.repository }} scheduled job failure 32 | content: ${{ github.server_url}}/${{ github.repository }}/actions/runs/${{ github.run_id }} failed. 33 | -------------------------------------------------------------------------------- /.github/workflows/breakage-against-macos-x86-ponyc-latest.yml: -------------------------------------------------------------------------------- 1 | name: x86-64 macOS ponyc update breakage test 2 | 3 | on: 4 | repository_dispatch: 5 | types: [ponyc-x86_64-macos-nightly-released] 6 | 7 | permissions: 8 | packages: read 9 | 10 | jobs: 11 | vs-ponyc-main-macos: 12 | name: Verify main against ponyc main on x86-64 macOS 13 | runs-on: macos-13 14 | steps: 15 | - uses: actions/checkout@v4.1.1 16 | - name: install pony tools 17 | run: bash .ci-scripts/macos-x86-install-pony-tools.bash nightly 18 | - name: Test with the most recent ponyc release 19 | run: | 20 | export PATH=/tmp/corral/bin/:/tmp/ponyc/bin/:$PATH 21 | make test 22 | - name: Send alert on failure 23 | if: ${{ failure() }} 24 | uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 25 | with: 26 | api-key: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_API_KEY }} 27 | email: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_EMAIL }} 28 | organization-url: 'https://ponylang.zulipchat.com/' 29 | to: notifications 30 | type: stream 31 | topic: ${{ github.repository }} scheduled job failure 32 | content: ${{ github.server_url}}/${{ github.repository }}/actions/runs/${{ github.run_id }} failed. 33 | -------------------------------------------------------------------------------- /.github/workflows/changelog-bot.yml: -------------------------------------------------------------------------------- 1 | name: Changelog Bot 2 | 3 | on: 4 | push: 5 | branches: 6 | - '**' 7 | tags-ignore: 8 | - '**' 9 | paths-ignore: 10 | - CHANGELOG.md 11 | 12 | permissions: 13 | packages: read 14 | pull-requests: read 15 | contents: write 16 | 17 | jobs: 18 | changelog-bot: 19 | runs-on: ubuntu-latest 20 | name: Update CHANGELOG.md 21 | steps: 22 | - name: Update Changelog 23 | uses: docker://ghcr.io/ponylang/changelog-bot-action:0.3.7 24 | with: 25 | GIT_USER_NAME: "Ponylang Main Bot" 26 | GIT_USER_EMAIL: "ponylang.main@gmail.com" 27 | env: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 29 | - name: Send alert on failure 30 | if: ${{ failure() }} 31 | uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 32 | with: 33 | api-key: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_API_KEY }} 34 | email: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_EMAIL }} 35 | organization-url: 'https://ponylang.zulipchat.com/' 36 | to: notifications 37 | type: stream 38 | topic: ${{ github.repository }} unattended job failure 39 | content: ${{ github.server_url}}/${{ github.repository }}/actions/runs/${{ github.run_id }} failed. 40 | -------------------------------------------------------------------------------- /.github/workflows/latest-docker-image.yml: -------------------------------------------------------------------------------- 1 | name: Build latest Docker images 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | concurrency: 9 | group: build-latest-docker-images 10 | cancel-in-progress: true 11 | 12 | permissions: 13 | packages: write 14 | 15 | jobs: 16 | build-latest-docker-image: 17 | name: Build and push latest Docker image 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/checkout@v4.1.1 21 | - name: Login to GitHub Container Registry 22 | # v2.2.0 23 | uses: docker/login-action@5139682d94efc37792e6b54386b5b470a68a4737 24 | with: 25 | registry: ghcr.io 26 | username: ${{ github.repository_owner }} 27 | password: ${{ secrets.GITHUB_TOKEN }} 28 | - name: Build and push 29 | run: bash .ci-scripts/release/build-latest-docker-images.bash 30 | - name: Send alert on failure 31 | if: ${{ failure() }} 32 | uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 33 | with: 34 | api-key: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_API_KEY }} 35 | email: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_EMAIL }} 36 | organization-url: 'https://ponylang.zulipchat.com/' 37 | to: notifications 38 | type: stream 39 | topic: ${{ github.repository }} scheduled job failure 40 | content: ${{ github.server_url}}/${{ github.repository }}/actions/runs/${{ github.run_id }} failed. 41 | 42 | prune-untagged-images: 43 | needs: 44 | - build-latest-docker-image 45 | 46 | name: Prune untagged images 47 | runs-on: ubuntu-latest 48 | steps: 49 | - name: Prune 50 | # v4.1.1 51 | uses: actions/delete-package-versions@0d39a63126868f5eefaa47169615edd3c0f61e20 52 | with: 53 | package-name: 'ponyup' 54 | package-type: 'container' 55 | min-versions-to-keep: 1 56 | delete-only-untagged-versions: 'true' 57 | - name: Send alert on failure 58 | if: ${{ failure() }} 59 | uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 60 | with: 61 | api-key: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_API_KEY }} 62 | email: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_EMAIL }} 63 | organization-url: 'https://ponylang.zulipchat.com/' 64 | to: notifications 65 | type: stream 66 | topic: ${{ github.repository }} scheduled job failure 67 | content: ${{ github.server_url}}/${{ github.repository }}/actions/runs/${{ github.run_id }} failed. 68 | -------------------------------------------------------------------------------- /.github/workflows/lint-action-workflows.yml: -------------------------------------------------------------------------------- 1 | name: Lint GitHub Action Workflows 2 | 3 | on: pull_request 4 | 5 | concurrency: 6 | group: lint-actions-${{ github.ref }} 7 | cancel-in-progress: true 8 | 9 | permissions: 10 | packages: read 11 | 12 | jobs: 13 | lint: 14 | name: Lint 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@v4.1.1 19 | - name: Check workflow files 20 | uses: docker://ghcr.io/ponylang/shared-docker-ci-actionlint:20250119 21 | with: 22 | args: -color 23 | -------------------------------------------------------------------------------- /.github/workflows/nightlies.yml: -------------------------------------------------------------------------------- 1 | name: Nightlies 2 | 3 | on: 4 | schedule: 5 | - cron: "0 0 * * *" 6 | 7 | permissions: 8 | packages: read 9 | 10 | jobs: 11 | # Currently, GitHub actions supplied by GH like checkout and cache do not work 12 | # in musl libc environments on arm64. We can work around this by running 13 | # those actions on the host and then "manually" doing our work that would 14 | # normally be done "in the musl container" by starting the container ourselves 15 | # for various steps by invoking docker directly. 16 | # 17 | # This is not in line with our standard pattern of "just do it all in the 18 | # container" but is required to work around the GitHub actions limitation 19 | # documented above. 20 | arm64-unknown-linux-nightly: 21 | name: Build and upload arm64-unknown-linux-nightly to Cloudsmith 22 | runs-on: ubuntu-24.04-arm 23 | steps: 24 | - name: Checkout 25 | uses: actions/checkout@v4.1.1 26 | - name: Pull Docker image 27 | run: docker pull ghcr.io/ponylang/shared-docker-ci-arm64-unknown-linux-builder-with-libressl-4.0.0:latest 28 | - name: Build and upload 29 | run: | 30 | docker run --rm \ 31 | -v ${{ github.workspace }}:/root/project \ 32 | -w /root/project \ 33 | -e CLOUDSMITH_API_KEY=${{ secrets.CLOUDSMITH_API_KEY }} \ 34 | -e GITHUB_REPOSITORY=${{ github.repository }} \ 35 | ghcr.io/ponylang/shared-docker-ci-arm64-unknown-linux-builder-with-libressl-4.0.0:latest \ 36 | bash .ci-scripts/release/arm64-unknown-linux-nightly.bash 37 | - name: Send alert on failure 38 | if: ${{ failure() }} 39 | uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 40 | with: 41 | api-key: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_API_KEY }} 42 | email: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_EMAIL }} 43 | organization-url: 'https://ponylang.zulipchat.com/' 44 | to: notifications 45 | type: stream 46 | topic: ${{ github.repository }} scheduled job failure 47 | content: ${{ github.server_url}}/${{ github.repository }}/actions/runs/${{ github.run_id }} failed. 48 | 49 | x86-64-unknown-linux-nightly: 50 | name: Build and upload x86-64-unknown-linux-nightly to Cloudsmith 51 | runs-on: ubuntu-latest 52 | container: 53 | image: ghcr.io/ponylang/shared-docker-ci-x86-64-unknown-linux-builder-with-libressl-4.0.0:release 54 | steps: 55 | - uses: actions/checkout@v4.1.1 56 | - name: Build and upload 57 | run: bash .ci-scripts/release/x86-64-unknown-linux-nightly.bash 58 | env: 59 | CLOUDSMITH_API_KEY: ${{ secrets.CLOUDSMITH_API_KEY }} 60 | - name: Send alert on failure 61 | if: ${{ failure() }} 62 | uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 63 | with: 64 | api-key: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_API_KEY }} 65 | email: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_EMAIL }} 66 | organization-url: 'https://ponylang.zulipchat.com/' 67 | to: notifications 68 | type: stream 69 | topic: ${{ github.repository }} scheduled job failure 70 | content: ${{ github.server_url}}/${{ github.repository }}/actions/runs/${{ github.run_id }} failed. 71 | 72 | x86-64-pc-windows-msvc-nightly: 73 | name: Build and upload x86-64-pc-windows-msvc-nightly to Cloudsmith 74 | runs-on: windows-2022 75 | steps: 76 | - uses: actions/checkout@v4.1.1 77 | - name: Build and upload 78 | run: | 79 | python.exe -m pip install --upgrade cloudsmith-cli 80 | Invoke-WebRequest https://dl.cloudsmith.io/public/ponylang/releases/raw/versions/latest/ponyc-x86-64-pc-windows-msvc.zip -OutFile C:\ponyc.zip; 81 | Expand-Archive -Force -Path C:\ponyc.zip -DestinationPath C:\ponyc; 82 | Invoke-WebRequest https://dl.cloudsmith.io/public/ponylang/releases/raw/versions/latest/corral-x86-64-pc-windows-msvc.zip -OutFile C:\corral.zip; 83 | Expand-Archive -Force -Path C:\corral.zip -DestinationPath C:\ponyc; 84 | $env:PATH = 'C:\ponyc\bin;' + $env:PATH; 85 | .\make.ps1 -Command fetch; 86 | .\make.ps1 -Command build; 87 | .\make.ps1 -Command install; 88 | .\make.ps1 -Command package; 89 | $version = (Get-Date).ToString("yyyyMMdd"); cloudsmith push raw --version $version --api-key $env:CLOUDSMITH_API_KEY --summary "The Pony toolchain multiplexer" --description "https://github.com/ponylang/ponyup" ponylang/nightlies build\ponyup-x86-64-pc-windows-msvc.zip 90 | env: 91 | CLOUDSMITH_API_KEY: ${{ secrets.CLOUDSMITH_API_KEY }} 92 | - name: Send alert on failure 93 | if: ${{ failure() }} 94 | uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 95 | with: 96 | api-key: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_API_KEY }} 97 | email: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_EMAIL }} 98 | organization-url: 'https://ponylang.zulipchat.com/' 99 | to: notifications 100 | type: stream 101 | topic: ${{ github.repository }} scheduled job failure 102 | content: ${{ github.server_url}}/${{ github.repository }}/actions/runs/${{ github.run_id }} failed. 103 | 104 | x86-64-apple-darwin-nightly: 105 | name: Build and upload x86-64-apple-darwin-nightly to Cloudsmith 106 | runs-on: macos-13 107 | steps: 108 | - uses: actions/checkout@v4.1.1 109 | - name: install pony tools 110 | run: bash .ci-scripts/macos-x86-install-pony-tools.bash release 111 | - name: brew install dependencies 112 | run: brew install coreutils 113 | - name: pip install dependencies 114 | run: pip3 install --upgrade cloudsmith-cli 115 | - name: Build and upload 116 | run: bash .ci-scripts/release/x86-64-apple-darwin-nightly.bash 117 | env: 118 | CLOUDSMITH_API_KEY: ${{ secrets.CLOUDSMITH_API_KEY }} 119 | - name: Send alert on failure 120 | if: ${{ failure() }} 121 | uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 122 | with: 123 | api-key: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_API_KEY }} 124 | email: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_EMAIL }} 125 | organization-url: 'https://ponylang.zulipchat.com/' 126 | to: notifications 127 | type: stream 128 | topic: ${{ github.repository }} scheduled job failure 129 | content: ${{ github.server_url}}/${{ github.repository }}/actions/runs/${{ github.run_id }} failed. 130 | 131 | arm64-apple-darwin-nightly: 132 | name: Build and upload arm64-apple-darwin-nightly to Cloudsmith 133 | runs-on: macos-15 134 | steps: 135 | - uses: actions/checkout@v4.1.1 136 | - name: install pony tools 137 | run: bash .ci-scripts/macos-arm64-install-pony-tools.bash release 138 | - name: brew install dependencies 139 | run: brew install coreutils 140 | - name: pip install dependencies 141 | run: pip3 install --upgrade --break-system-packages cloudsmith-cli 142 | - name: Build and upload 143 | run: bash .ci-scripts/release/arm64-apple-darwin-nightly.bash 144 | env: 145 | CLOUDSMITH_API_KEY: ${{ secrets.CLOUDSMITH_API_KEY }} 146 | - name: Send alert on failure 147 | if: ${{ failure() }} 148 | uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 149 | with: 150 | api-key: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_API_KEY }} 151 | email: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_EMAIL }} 152 | organization-url: 'https://ponylang.zulipchat.com/' 153 | to: notifications 154 | type: stream 155 | topic: ${{ github.repository }} scheduled job failure 156 | content: ${{ github.server_url}}/${{ github.repository }}/actions/runs/${{ github.run_id }} failed. 157 | -------------------------------------------------------------------------------- /.github/workflows/pr.yml: -------------------------------------------------------------------------------- 1 | name: PR 2 | 3 | on: pull_request 4 | 5 | concurrency: 6 | group: pr-${{ github.ref }} 7 | cancel-in-progress: true 8 | 9 | permissions: 10 | packages: read 11 | 12 | jobs: 13 | superlinter: 14 | name: Lint bash, docker, markdown, and yaml 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v4.1.1 18 | - name: Lint codebase 19 | uses: docker://github/super-linter:v3.8.3 20 | env: 21 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 22 | VALIDATE_ALL_CODEBASE: true 23 | VALIDATE_BASH: true 24 | VALIDATE_DOCKERFILE: true 25 | VALIDATE_MD: true 26 | VALIDATE_YAML: true 27 | 28 | validate-docker-image-builds: 29 | name: Validate Docker image builds 30 | runs-on: ubuntu-latest 31 | steps: 32 | - uses: actions/checkout@v4.1.1 33 | - name: Docker build 34 | run: "docker build --pull ." 35 | 36 | verify-changelog: 37 | name: Verify CHANGELOG is valid 38 | runs-on: ubuntu-latest 39 | container: 40 | image: ghcr.io/ponylang/changelog-tool:release 41 | steps: 42 | - uses: actions/checkout@v4.1.1 43 | - name: Verify CHANGELOG 44 | run: changelog-tool verify 45 | 46 | # Currently, GitHub actions supplied by GH like checkout and cache do not work 47 | # in musl libc environments on arm64. We can work around this by running 48 | # those actions on the host and then "manually" doing our work that would 49 | # normally be done "in the musl container" by starting the container ourselves 50 | # for various steps by invoking docker directly. 51 | # 52 | # This is not in line with our standard pattern of "just do it all in the 53 | # container" but is required to work around the GitHub actions limitation 54 | # documented above. 55 | arm64-alpine3_21-bootstrap: 56 | name: arm64 Alpine 3.21 bootstrap 57 | runs-on: ubuntu-24.04-arm 58 | steps: 59 | - name: Checkout 60 | uses: actions/checkout@v4.1.1 61 | - name: Login to GitHub Container Registry 62 | uses: docker/login-action@v3 63 | with: 64 | registry: ghcr.io 65 | username: ${{ github.actor }} 66 | password: ${{ secrets.GITHUB_TOKEN }} 67 | - name: Pull Docker image 68 | run: docker pull ghcr.io/ponylang/ponyup-ci-alpine3.21-bootstrap-tester:20250603 69 | - name: Bootstrap test 70 | run: | 71 | docker run --rm \ 72 | -v ${{ github.workspace }}:/root/project \ 73 | -w /root/project \ 74 | -e SSL=0.9.0 \ 75 | ghcr.io/ponylang/ponyup-ci-alpine3.21-bootstrap-tester:20250603 \ 76 | .ci-scripts/test-bootstrap.sh 77 | 78 | arm64-ubuntu24_04-bootstrap: 79 | name: arm64 Ubuntu 24.04 bootstrap 80 | runs-on: ubuntu-24.04-arm 81 | container: 82 | image: ghcr.io/ponylang/ponyup-ci-ubuntu24.04-bootstrap-tester:20250603 83 | steps: 84 | - uses: actions/checkout@v4.1.1 85 | - name: Bootstrap test 86 | run: SSL=3.0.x .ci-scripts/test-bootstrap.sh 87 | 88 | x86-64-alpine3_20-bootstrap: 89 | name: x86-64 Alpine 3.20 bootstrap 90 | runs-on: ubuntu-latest 91 | container: 92 | image: ghcr.io/ponylang/ponyup-ci-alpine3.20-bootstrap-tester:20250603 93 | steps: 94 | - uses: actions/checkout@v4.1.1 95 | - name: Bootstrap test 96 | run: SSL=0.9.0 .ci-scripts/test-bootstrap.sh 97 | 98 | x86-64-alpine3_21-bootstrap: 99 | name: x86-64 Alpine 3.21 bootstrap 100 | runs-on: ubuntu-latest 101 | container: 102 | image: ghcr.io/ponylang/ponyup-ci-alpine3.21-bootstrap-tester:20250603 103 | steps: 104 | - uses: actions/checkout@v4.1.1 105 | - name: Bootstrap test 106 | run: SSL=0.9.0 .ci-scripts/test-bootstrap.sh 107 | 108 | x86-64-ubuntu24_04-bootstrap: 109 | name: x86-64 Ubuntu 24.04 bootstrap 110 | runs-on: ubuntu-latest 111 | container: 112 | image: ghcr.io/ponylang/ponyup-ci-ubuntu24.04-bootstrap-tester:20250603 113 | steps: 114 | - uses: actions/checkout@v4.1.1 115 | - name: Bootstrap test 116 | run: SSL=3.0.x .ci-scripts/test-bootstrap.sh 117 | 118 | alpine-bootstrap: 119 | name: Alpine bootstrap 120 | runs-on: ubuntu-latest 121 | container: 122 | image: ghcr.io/ponylang/ponyup-ci-alpine-bootstrap-tester:20241204 123 | steps: 124 | - uses: actions/checkout@v4.1.1 125 | - name: Bootstrap test 126 | run: SSL=0.9.0 .ci-scripts/test-bootstrap.sh 127 | 128 | fedora41-bootstrap: 129 | name: Fedora 41 bootstrap 130 | runs-on: ubuntu-latest 131 | container: 132 | image: ghcr.io/ponylang/ponyup-ci-fedora41-bootstrap-tester:20241205 133 | steps: 134 | - uses: actions/checkout@v4.1.1 135 | - name: Bootstrap test 136 | run: SSL=3.0.x .ci-scripts/test-bootstrap.sh 137 | 138 | ubuntu22_04-bootstrap: 139 | name: Ubuntu 22.04 bootstrap 140 | runs-on: ubuntu-latest 141 | container: 142 | image: ghcr.io/ponylang/ponyup-ci-ubuntu22.04-bootstrap-tester:20230830 143 | steps: 144 | - uses: actions/checkout@v4.1.1 145 | - name: Bootstrap test 146 | run: SSL=3.0.x .ci-scripts/test-bootstrap.sh 147 | 148 | arm64-macos-bootstrap: 149 | name: arm64 MacOS bootstrap 150 | runs-on: macos-15 151 | steps: 152 | - uses: actions/checkout@v4.1.1 153 | - name: Install dependencies 154 | # libressl gets installed but is returning a non-zero exit code, 155 | # so we have to soldier on through the stupidity 156 | continue-on-error: true 157 | run: | 158 | brew update 159 | brew install libressl 160 | - name: Bootstrap test 161 | run: SSL=0.9.0 .ci-scripts/test-bootstrap.sh 162 | 163 | x86-64-macos-bootstrap: 164 | name: x86-64 MacOS bootstrap 165 | runs-on: macos-13 166 | steps: 167 | - uses: actions/checkout@v4.1.1 168 | - name: Install dependencies 169 | # libressl gets installed but is returning a non-zero exit code, 170 | # so we have to soldier on through the stupidity 171 | continue-on-error: true 172 | run: | 173 | brew update 174 | brew install libressl 175 | - name: Bootstrap test 176 | run: SSL=0.9.0 .ci-scripts/test-bootstrap.sh 177 | 178 | # Currently, GitHub actions supplied by GH like checkout and cache do not work 179 | # in musl libc environments on arm64. We can work around this by running 180 | # those actions on the host and then "manually" doing our work that would 181 | # normally be done "in the musl container" by starting the container ourselves 182 | # for various steps by invoking docker directly. 183 | # 184 | # This is not in line with our standard pattern of "just do it all in the 185 | # container" but is required to work around the GitHub actions limitation 186 | # documented above. 187 | arm64-linux: 188 | name: arm64 Linux tests 189 | runs-on: ubuntu-24.04-arm 190 | steps: 191 | - name: Checkout 192 | uses: actions/checkout@v4.1.1 193 | - name: Pull Docker image 194 | run: docker pull ghcr.io/ponylang/shared-docker-ci-arm64-unknown-linux-builder-with-libressl-4.0.0:latest 195 | - name: Test with most recent ponyc release 196 | run: | 197 | docker run --rm \ 198 | -v ${{ github.workspace }}:/root/project \ 199 | -w /root/project \ 200 | ghcr.io/ponylang/shared-docker-ci-arm64-unknown-linux-builder-with-libressl-4.0.0:latest \ 201 | make test 202 | 203 | x86-64-linux: 204 | name: x86-64 Linux tests 205 | runs-on: ubuntu-latest 206 | container: 207 | image: ghcr.io/ponylang/shared-docker-ci-x86-64-unknown-linux-builder-with-libressl-4.0.0:release 208 | steps: 209 | - uses: actions/checkout@v4.1.1 210 | - name: Test with the most recent ponyc release 211 | run: make test 212 | 213 | x86-64-macos: 214 | name: x86-64 MacOS tests 215 | runs-on: macos-13 216 | steps: 217 | - uses: actions/checkout@v4.1.1 218 | - name: install pony tools 219 | run: bash .ci-scripts/macos-x86-install-pony-tools.bash release 220 | - name: Test with the most recent ponyc release 221 | run: | 222 | export PATH="/tmp/corral/bin:/tmp/ponyc/bin/:$PATH" 223 | make test 224 | 225 | arm64-macos: 226 | name: arm64 MacOS tests 227 | runs-on: macos-15 228 | steps: 229 | - uses: actions/checkout@v4.1.1 230 | - name: install pony tools 231 | run: bash .ci-scripts/macos-arm64-install-pony-tools.bash release 232 | - name: Test with the most recent ponyc release 233 | run: | 234 | export PATH="/tmp/corral/bin:/tmp/ponyc/bin/:$PATH" 235 | make test 236 | 237 | x86-64-windows: 238 | name: x86-64 Windows tests 239 | runs-on: windows-2022 240 | steps: 241 | - uses: actions/checkout@v4.1.1 242 | - name: Test with most recent ponyc release 243 | run: | 244 | Invoke-WebRequest https://dl.cloudsmith.io/public/ponylang/releases/raw/versions/latest/ponyc-x86-64-pc-windows-msvc.zip -OutFile C:\ponyc.zip; 245 | Expand-Archive -Path C:\ponyc.zip -DestinationPath C:\ponyc; 246 | Invoke-WebRequest https://dl.cloudsmith.io/public/ponylang/releases/raw/versions/latest/corral-x86-64-pc-windows-msvc.zip -OutFile C:\corral.zip; 247 | Expand-Archive -Path C:\corral.zip -DestinationPath C:\ponyc; 248 | $env:PATH = 'C:\ponyc\bin;' + $env:PATH; 249 | .\make.ps1 -Command fetch 2>&1 250 | .\make.ps1 -Command build 2>&1 251 | .\make.ps1 -Command test 2>&1 252 | -------------------------------------------------------------------------------- /.github/workflows/prepare-for-a-release.yml: -------------------------------------------------------------------------------- 1 | name: Prepare for a release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'release-[0-9]+.[0-9]+.[0-9]+' 7 | 8 | concurrency: prepare-for-a-release 9 | 10 | permissions: 11 | packages: read 12 | contents: write 13 | 14 | jobs: 15 | # all tasks that need to be done before we add an X.Y.Z tag 16 | # should be done as a step in the pre-tagging job. 17 | # think of it like this... if when you later checkout the tag for a release, 18 | # should the change be there? if yes, do it here. 19 | pre-tagging: 20 | name: Tasks run before tagging the release 21 | runs-on: ubuntu-latest 22 | steps: 23 | - name: Checkout main 24 | uses: actions/checkout@v4.1.1 25 | with: 26 | ref: "main" 27 | token: ${{ secrets.RELEASE_TOKEN }} 28 | - name: Update CHANGELOG.md 29 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 30 | with: 31 | entrypoint: update-changelog-for-release 32 | env: 33 | GIT_USER_NAME: "Ponylang Main Bot" 34 | GIT_USER_EMAIL: "ponylang.main@gmail.com" 35 | - name: Update VERSION 36 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 37 | with: 38 | entrypoint: update-version-in-VERSION 39 | env: 40 | GIT_USER_NAME: "Ponylang Main Bot" 41 | GIT_USER_EMAIL: "ponylang.main@gmail.com" 42 | - name: Update corral.json 43 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 44 | with: 45 | entrypoint: update-version-in-corral-json 46 | env: 47 | GIT_USER_NAME: "Ponylang Main Bot" 48 | GIT_USER_EMAIL: "ponylang.main@gmail.com" 49 | 50 | # tag for release 51 | # this will kick off the next stage of the release process 52 | # no additional steps should be added to this job 53 | tag-release: 54 | name: Tag the release 55 | needs: 56 | - pre-tagging 57 | runs-on: ubuntu-latest 58 | steps: 59 | - name: Checkout main 60 | uses: actions/checkout@v4.1.1 61 | with: 62 | ref: "main" 63 | token: ${{ secrets.RELEASE_TOKEN }} 64 | - name: Trigger artefact creation 65 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 66 | with: 67 | entrypoint: trigger-artefact-creation 68 | env: 69 | GIT_USER_NAME: "Ponylang Main Bot" 70 | GIT_USER_EMAIL: "ponylang.main@gmail.com" 71 | 72 | # all cleanup tags that should happen after tagging for release should happen 73 | # in the post-tagging job. examples of things you might do: 74 | # add a new unreleased section to a changelog 75 | # set a version back to "snapshot" 76 | # in general, post-tagging is for "going back to normal" from tasks that were 77 | # done during the pre-tagging job 78 | post-tagging: 79 | name: Tasks run after tagging the release 80 | needs: 81 | - tag-release 82 | runs-on: ubuntu-latest 83 | steps: 84 | - name: Checkout main 85 | uses: actions/checkout@v4.1.1 86 | with: 87 | ref: "main" 88 | token: ${{ secrets.RELEASE_TOKEN }} 89 | - name: Add "unreleased" section to CHANGELOG.md 90 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 91 | with: 92 | entrypoint: add-unreleased-section-to-changelog 93 | env: 94 | GIT_USER_NAME: "Ponylang Main Bot" 95 | GIT_USER_EMAIL: "ponylang.main@gmail.com" 96 | -------------------------------------------------------------------------------- /.github/workflows/release-notes-reminder-bot.yml: -------------------------------------------------------------------------------- 1 | name: Release Notes Reminder 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - labeled 7 | 8 | permissions: 9 | packages: read 10 | pull-requests: write 11 | 12 | jobs: 13 | release-note-reminder: 14 | runs-on: ubuntu-latest 15 | name: Prompt to add release notes 16 | steps: 17 | - name: Prompt to add release notes 18 | uses: docker://ghcr.io/ponylang/release-notes-reminder-bot-action:0.1.1 19 | env: 20 | API_CREDENTIALS: ${{ secrets.PONYLANG_MAIN_API_TOKEN }} 21 | 22 | -------------------------------------------------------------------------------- /.github/workflows/release-notes.yml: -------------------------------------------------------------------------------- 1 | name: Release Notes 2 | 3 | on: 4 | push: 5 | branches: 6 | - '**' 7 | tags-ignore: 8 | - '**' 9 | paths-ignore: 10 | - .release-notes/next-release.md 11 | - .release-notes/\d+.\d+.\d+.md 12 | 13 | permissions: 14 | packages: read 15 | contents: write 16 | 17 | jobs: 18 | release-notes: 19 | runs-on: ubuntu-latest 20 | name: Update release notes 21 | steps: 22 | - name: Update 23 | uses: docker://ghcr.io/ponylang/release-notes-bot-action:0.3.10 24 | with: 25 | GIT_USER_NAME: "Ponylang Main Bot" 26 | GIT_USER_EMAIL: "ponylang.main@gmail.com" 27 | env: 28 | API_CREDENTIALS: ${{ secrets.GITHUB_TOKEN }} 29 | - name: Send alert on failure 30 | if: ${{ failure() }} 31 | uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 32 | with: 33 | api-key: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_API_KEY }} 34 | email: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_EMAIL }} 35 | organization-url: 'https://ponylang.zulipchat.com/' 36 | to: notifications 37 | type: stream 38 | topic: ${{ github.repository }} scheduled job failure 39 | content: ${{ github.server_url}}/${{ github.repository }}/actions/runs/${{ github.run_id }} failed. 40 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - '[0-9]+.[0-9]+.[0-9]+' 7 | 8 | concurrency: release 9 | 10 | permissions: 11 | packages: write 12 | contents: write 13 | 14 | jobs: 15 | # validation to assure that we should in fact continue with the release should 16 | # be done here. the primary reason for this step is to verify that the release 17 | # was started correctly by pushing a `release-X.Y.Z` tag rather than `X.Y.Z`. 18 | pre-artefact-creation: 19 | name: Tasks to run before artefact creation 20 | runs-on: ubuntu-latest 21 | steps: 22 | - name: Checkout main 23 | uses: actions/checkout@v4.1.1 24 | with: 25 | ref: "main" 26 | token: ${{ secrets.RELEASE_TOKEN }} 27 | - name: Validate CHANGELOG 28 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 29 | with: 30 | entrypoint: pre-artefact-changelog-check 31 | 32 | arm64-unknown-linux-release: 33 | name: Build and upload arm64-unknown-linux to Cloudsmith 34 | runs-on: ubuntu-latest 35 | needs: 36 | - pre-artefact-creation 37 | steps: 38 | - name: Checkout 39 | uses: actions/checkout@v4.1.1 40 | - name: Pull Docker image 41 | run: docker pull ghcr.io/ponylang/shared-docker-ci-arm64-unknown-linux-builder-with-libressl-4.0.0:latest 42 | - name: Build and upload 43 | run: | 44 | docker run --rm \ 45 | -v ${{ github.workspace }}:/root/project \ 46 | -w /root/project \ 47 | -e CLOUDSMITH_API_KEY=${{ secrets.CLOUDSMITH_API_KEY }} \ 48 | -e GITHUB_REPOSITORY=${{ github.repository }} \ 49 | ghcr.io/ponylang/shared-docker-ci-arm64-unknown-linux-builder-with-libressl-4.0.0:latest \ 50 | bash .ci-scripts/release/arm64-unknown-linux-release.bash 51 | 52 | x86-64-unknown-linux-release: 53 | name: Build and upload x86-64-unknown-linux to Cloudsmith 54 | runs-on: ubuntu-latest 55 | needs: 56 | - pre-artefact-creation 57 | container: 58 | image: ghcr.io/ponylang/shared-docker-ci-x86-64-unknown-linux-builder-with-libressl-4.0.0:release 59 | steps: 60 | - uses: actions/checkout@v4.1.1 61 | - name: Build and upload 62 | run: bash .ci-scripts/release/x86-64-unknown-linux-release.bash 63 | env: 64 | CLOUDSMITH_API_KEY: ${{ secrets.CLOUDSMITH_API_KEY }} 65 | 66 | x86-64-apple-darwin-release: 67 | name: Build and upload x86-64-apple-darwin to Cloudsmith 68 | runs-on: macos-13 69 | needs: 70 | - pre-artefact-creation 71 | steps: 72 | - uses: actions/checkout@v4.1.1 73 | - name: install pony tools 74 | run: bash .ci-scripts/macos-x86-install-pony-tools.bash release 75 | - name: brew install dependencies 76 | run: brew install coreutils 77 | - name: pip install dependencies 78 | run: pip3 install --upgrade cloudsmith-cli 79 | - name: Build and upload 80 | run: bash .ci-scripts/release/x86-64-apple-darwin-release.bash 81 | env: 82 | CLOUDSMITH_API_KEY: ${{ secrets.CLOUDSMITH_API_KEY }} 83 | 84 | arm64-apple-darwin-release: 85 | name: Build and upload arm64-apple-darwin to Cloudsmith 86 | runs-on: macos-15 87 | needs: 88 | - pre-artefact-creation 89 | steps: 90 | - uses: actions/checkout@v4.1.1 91 | - name: install pony tools 92 | run: bash .ci-scripts/macos-arm64-install-pony-tools.bash release 93 | - name: brew install dependencies 94 | run: brew install coreutils 95 | - name: pip install dependencies 96 | run: pip3 install --upgrade --break-system-packages cloudsmith-cli 97 | - name: Build and upload 98 | run: bash .ci-scripts/release/arm64-apple-darwin-release.bash 99 | env: 100 | CLOUDSMITH_API_KEY: ${{ secrets.CLOUDSMITH_API_KEY }} 101 | 102 | x86-64-pc-windows-msvc-release: 103 | name: Build and upload x86-64-pc-windows-msvc-release to Cloudsmith 104 | runs-on: windows-2022 105 | needs: 106 | - pre-artefact-creation 107 | steps: 108 | - uses: actions/checkout@v4.1.1 109 | - name: Build and upload 110 | run: | 111 | python.exe -m pip install --upgrade cloudsmith-cli 112 | Invoke-WebRequest https://dl.cloudsmith.io/public/ponylang/releases/raw/versions/latest/ponyc-x86-64-pc-windows-msvc.zip -OutFile C:\ponyc.zip; 113 | Expand-Archive -Force -Path C:\ponyc.zip -DestinationPath C:\ponyc; 114 | Invoke-WebRequest https://dl.cloudsmith.io/public/ponylang/releases/raw/versions/latest/corral-x86-64-pc-windows-msvc.zip -OutFile C:\corral.zip; 115 | Expand-Archive -Force -Path C:\corral.zip -DestinationPath C:\ponyc; 116 | $env:PATH = 'C:\ponyc\bin;' + $env:PATH; 117 | .\make.ps1 -Command fetch; 118 | .\make.ps1 -Command build; 119 | .\make.ps1 -Command install; 120 | .\make.ps1 -Command package; 121 | $version = (Get-Content .\VERSION); cloudsmith push raw --version $version --api-key $env:CLOUDSMITH_API_KEY --summary "The Pony toolchain multiplexer" --description "https://github.com/ponylang/ponyup" ponylang/releases build\ponyup-x86-64-pc-windows-msvc.zip 122 | env: 123 | CLOUDSMITH_API_KEY: ${{ secrets.CLOUDSMITH_API_KEY }} 124 | 125 | build-release-docker-images: 126 | name: Build and push release Docker images 127 | runs-on: ubuntu-latest 128 | needs: 129 | - pre-artefact-creation 130 | steps: 131 | - uses: actions/checkout@v4.1.1 132 | - name: Login to GitHub Container Registry 133 | # v2.2.0 134 | uses: docker/login-action@5139682d94efc37792e6b54386b5b470a68a4737 135 | with: 136 | registry: ghcr.io 137 | username: ${{ github.repository_owner }} 138 | password: ${{ secrets.GITHUB_TOKEN }} 139 | - name: Build and push 140 | run: bash .ci-scripts/release/build-docker-images-on-release.bash 141 | 142 | update-latest-release-tag: 143 | name: Update latest-release tag 144 | runs-on: ubuntu-latest 145 | needs: 146 | - pre-artefact-creation 147 | steps: 148 | - uses: actions/checkout@v4.1.1 149 | - name: Tag 150 | run: | 151 | git tag --force latest-release 152 | git push --force "https://${TOKEN}@github.com/${GITHUB_REPOSITORY}.git" latest-release 153 | env: 154 | TOKEN: ${{ secrets.RELEASE_TOKEN }} 155 | 156 | trigger-release-announcement: 157 | name: Trigger release announcement 158 | runs-on: ubuntu-latest 159 | needs: 160 | - arm64-unknown-linux-release 161 | - x86-64-unknown-linux-release 162 | - x86-64-pc-windows-msvc-release 163 | - x86-64-apple-darwin-release 164 | - arm64-apple-darwin-release 165 | - build-release-docker-images 166 | - update-latest-release-tag 167 | steps: 168 | - uses: actions/checkout@v4.1.1 169 | with: 170 | ref: "main" 171 | token: ${{ secrets.RELEASE_TOKEN }} 172 | - name: Trigger 173 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 174 | with: 175 | entrypoint: trigger-release-announcement 176 | env: 177 | GIT_USER_NAME: "Ponylang Main Bot" 178 | GIT_USER_EMAIL: "ponylang.main@gmail.com" 179 | -------------------------------------------------------------------------------- /.github/workflows/remove-discuss-during-sync.yml: -------------------------------------------------------------------------------- 1 | name: Remove discuss during sync label 2 | 3 | on: 4 | issues: 5 | types: 6 | - closed 7 | pull_request_target: 8 | types: 9 | - closed 10 | 11 | permissions: 12 | pull-requests: write 13 | 14 | jobs: 15 | remove-label: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Remove label 19 | uses: andymckay/labeler@467347716a3bdbca7f277cb6cd5fa9c5205c5412 20 | with: 21 | repo-token: ${{ secrets.PONYLANG_MAIN_API_TOKEN }} 22 | remove-labels: "discuss during sync" 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.pony_test/ 2 | /.vscode/ 3 | /build/ 4 | /cmd/version.pony 5 | /_corral/ 6 | /_repos/ 7 | lock.json -------------------------------------------------------------------------------- /.markdownlintignore: -------------------------------------------------------------------------------- 1 | CHANGELOG.md 2 | CODE_OF_CONDUCT.md 3 | .release-notes/* 4 | -------------------------------------------------------------------------------- /.release-notes/0.6.0.md: -------------------------------------------------------------------------------- 1 | ## Use `XDG_DATA_HOME` for install prefix in init script when set 2 | 3 | The `ponyup_init.sh` script will now set the default install prefix to the `XDG_DATA_HOME` environment variable if the variable is set. 4 | 5 | ## Select uses latest version if none is specified 6 | 7 | The select command will now link the latest installed version of a given package by default. For example, if `ponyc-release-0.36.0-x86_64-linux-gnu` is the latest release version of ponyc installed then it can now be selected with the command `ponyup select ponyc release` or the command `ponyup select ponyc release-latest`. 8 | 9 | ## Update Dockerfile to Alpine 3.12 10 | 11 | The ponyup Docker container has been updated from being based on Alpine 3.11 to Alpine 3.12. This shouldn't be a breaking change for pretty much anyone, but might be if you are using the ponyup image as a base for other images and some package you rely on was removed from Alpine 3.12. 12 | 13 | -------------------------------------------------------------------------------- /.release-notes/0.6.1.md: -------------------------------------------------------------------------------- 1 | ## Incorrect initial ponyup version 2 | 3 | The init script has been updated to record the correct version of the initial ponyup install. 4 | 5 | ## Fix ponyup-init on FreeBSD 6 | 7 | There was a small typo in a variable name that broke 8 | running ponyup-init on FreeBSD. 9 | 10 | -------------------------------------------------------------------------------- /.release-notes/0.6.2.md: -------------------------------------------------------------------------------- 1 | ## Fix incorrect FreeBSD to Cloudsmith package mapping 2 | 3 | Ponyup now searches for FreeBSD packages on Cloudsmith using the `unknown` vendor field. This field was previously left out, resulting in failed queries. 4 | ## Switch support FreeBSD version 5 | 6 | We've switched our supported FreeBSD from 12.1 to 12.2. The switch means that FreeBSD packages are tested and built on FreeBSD 12.2 and we no longer do any testing or building on 12.1. 7 | 8 | You can continue using ponyup on FreeBSD 12.1 but we make no guarantees that it will work. 9 | 10 | ## Fix confusing and seemingly broken installation on MacOS 11 | 12 | MacOS installation looked like it was failing because it prompted for a libc version to install forcing the user to select "cancel" as the option. Ponyup was actually installed correctly, but the end user had no way of knowing. 13 | 14 | -------------------------------------------------------------------------------- /.release-notes/0.6.3.md: -------------------------------------------------------------------------------- 1 | ## Fix segfault in prebuilt Linux ponyup releases 2 | 3 | There was a bug in the Pony runtime related to opening sockets that could cause a segfault. The bug was fixed a few months ago, but our Linux ponyup releases were still being built with an older version (aka still with the bug) of the Pony runtime due to a stale build environment. 4 | 5 | -------------------------------------------------------------------------------- /.release-notes/0.6.4.md: -------------------------------------------------------------------------------- 1 | ## Switch supported FreeBSD to 13.0 2 | 3 | As of this release, we now do all FreeBSD testing on FreeBSD 13.0 and all ponyup prebuilt packages are built on FreeBSD 13.0. We will make a best effort to not break prior versions of FreeBSD while they are "supported". 4 | 5 | -------------------------------------------------------------------------------- /.release-notes/0.6.5.md: -------------------------------------------------------------------------------- 1 | ## Update to compile with Pony 0.44.0 2 | 3 | This release is solely so that we can be compiled with the most recent `ponyc` version. 4 | -------------------------------------------------------------------------------- /.release-notes/0.6.6.md: -------------------------------------------------------------------------------- 1 | ## Add Windows support 2 | 3 | Updated the app and test code to handle Windows. Note that on Windows, only `ponyup`, `ponyc`, and `corral` are supported packages. 4 | 5 | Instead of creating symbolic links, ponyup on Windows creates batch file shims in its bin directory (e.g. `ponyc.bat`) that call the selected versions with the given parameters. 6 | 7 | Added a `ponyup-init.ps1` bootstrapper script and updated the README to mention it. 8 | 9 | -------------------------------------------------------------------------------- /.release-notes/0.6.7.md: -------------------------------------------------------------------------------- 1 | ## Add ARM64 support 2 | 3 | We updated ponyup to correctly detect arm64 CPUs. Previously, ponyup defaulted to assuming that the current platform was x86_64, even when the user used the `--platform` flag to override this. 4 | 5 | ## Add support for MacOS on Apple Silicon 6 | 7 | You can now use ponyup on Apple Silicon MacOS computers. corral and ponyc are both available to install via ponyup and the ponyup install script recognizes MacOS on Apple Silicon and installs a prebuilt version of ponyup. 8 | 9 | -------------------------------------------------------------------------------- /.release-notes/0.6.8.md: -------------------------------------------------------------------------------- 1 | ## Update Dockerfile to Alpine 3.16 2 | 3 | The ponyup Docker container has been updated from being based on Alpine 3.12 to Alpine 3.16. This shouldn't be a breaking change for pretty much anyone, but might be if you are using the ponyup image as a base for other images and some package you rely on was removed from Alpine 3.16. 4 | 5 | Alpine 3.12 is no longer supported. Alpine 3.16 is supported through 2024. 6 | 7 | ## Fixed ponyup-init.sh crash when specifying --prefix 8 | 9 | When running `ponyup-init.sh` with the `--prefix` parameter, the script would crash because the `ponyup` invocation at the end of the script wasn't running with the same prefix. This minor change fixes that by also running `ponyup` with the `--prefix` parameter.` 10 | 11 | -------------------------------------------------------------------------------- /.release-notes/0.6.9.md: -------------------------------------------------------------------------------- 1 | ## Switch supported FreeBSD to 13.1 2 | 3 | As of this release, we now do all FreeBSD testing on FreeBSD 13.1 and all ponyup prebuilt packages are built on FreeBSD 13.1. We will make a best effort to not break prior versions of FreeBSD while they are "supported". 4 | 5 | -------------------------------------------------------------------------------- /.release-notes/0.7.0.md: -------------------------------------------------------------------------------- 1 | ## Remove macOS on Intel support 2 | 3 | We no longer support macOS on Intel. Going forward ponyup will only support macOS on Apple Silicon. 4 | 5 | ## Stop installing "generic gnu" ponyc builds 6 | 7 | Previously, on glibc based Linux distributions, the default setup of ponyup would install the "generic gnu" builds of ponyc. These "generic builds" only work on Linux distributions that are library compatible with the build environment. This use of "generic gnu" made it easy to install a ponyc that wouldn't work on the users platform even if we have ponyc builds for said distribution. 8 | 9 | We've stopped using the "generic gnu" builds and instead, on glibc Linux distributions, are using `lsb_release -d` to determine the distribution and if we support the distribution, set up ponyup to install ponyc builds for the distribution in question. If we don't support the distribution or recognize the output of `lsb_release`, an error message is displayed. 10 | 11 | -------------------------------------------------------------------------------- /.release-notes/0.8.0.md: -------------------------------------------------------------------------------- 1 | ## Switch supported MacOS version to Ventura 2 | 3 | We've switched our supported MacOS version from Monterey to Ventura. 4 | 5 | "Supported" means that all ponyup changes are tested on Ventura rather than Monterey and our pre-built ponyup distribution is built on Ventura. 6 | 7 | ## Drop Ubuntu 18.04 support 8 | 9 | Ubuntu 18.04 has reached its end of life date. We've dropped it as a supported platform for `ponyc` and `ponyup`. 10 | 11 | For `ponyup` that means, we no longer test against it when doing CI. Additinally, new installations of `ponyup` on Ubuntu 18.04 and related platforms won't recognize it as a supported package. If you install `ponyup` on such a platform, you'll need to set the platform to `ubuntu18.04` yourself. 12 | 13 | For `ponyc` the lack of support means that if you are using `ponyup` on Ubuntu 18.04 that it won't be able to install any version of `ponyc` from the point that we stopped supporting 18.04 for `ponyc`. Any `ponyc` from 0.55.0 on will not be able to be installed via `ponyup` and will need to instead be built from source. 14 | 15 | ## Add macOS on Intel as fully supported platform 16 | 17 | We've added macOS on Intel as a fully supported platform. This means that we test ponyup using macOS on Intel and provide nightly and release builds of ponyup for macOS on Intel. 18 | 19 | We plan to maintain ponyup as fully supported on macOS on Intel as long as we have a macOS on Intel environment or until Apple stops supporting new macOS releases on Intel CPUs. 20 | 21 | ## Drop FreeBSD support 22 | 23 | We no longer have any CI resources for maintaining FreeBSD versions of Pony tools. We've dropped FreeBSD as a fully-supported platform for `ponyc`, `corral`, and `ponyup`. 24 | 25 | For `ponyup` that means, we no longer test against it when doing CI. Additinally, new installations of `ponyup` on FreeBSD. If you install `ponyup` on such a platform, you'll need to set the platform yourself. 26 | 27 | For `ponyc` the lack of support means that if you are using `ponyup` on FreeBSD that it won't be able to install any version of `ponyc` from the point that we stopped supporting it for `ponyc`. Any `ponyc` from 0.56.0 on will not be able to be installed via `ponyup` and will need to instead be built from source. 28 | 29 | ## Temporarily drop macOS on Apple Silicon as fully supported platform 30 | 31 | We currently don't have a CI environment for macOS on Apple Silicon. This means that we can't test ponyup on macOS for Apple Silicon nor can we provide nightly and release binaries of ponyup for Apple Silicon computers. 32 | 33 | We are "temporarily" dropping support for ponyup on macOS on Apple Silicon. GitHub Actions is supposed to be adding support for Apple Silicon in Q4 of 2023. When Apple Silicon macOS runners are added, we'll elevate macOS on Apple Silicon back to a fully supported platform. 34 | 35 | In the meantime, we have CI for macOS on Intel which should provide reasonable assurance that we don't accidentally break macOS related functionality. 36 | 37 | -------------------------------------------------------------------------------- /.release-notes/0.8.1.md: -------------------------------------------------------------------------------- 1 | ## Use Alpine 3.18 as our base image 2 | 3 | Previously we were using Alpine 3.16. This should have no impact on anyone unless they are using this image as the base image for another. 4 | 5 | ## Add Fedora 39 support 6 | 7 | We've added support for identifying Fedora 39 and downloading packages for it. As of the time of this release, no release versions of `ponyc` are available- only nightly versions. Release versions of `ponyc` will be available once a version of `ponyc` post 0.58.1 is released. 8 | 9 | -------------------------------------------------------------------------------- /.release-notes/0.8.2.md: -------------------------------------------------------------------------------- 1 | ## Add MacOS on Apple Silicon as a fully supported platform 2 | 3 | In August of 2023, we had to drop MacOS on Apple Silicon as a fully supported platform. We had to move off of CirrusCI and in the process, lost access to Apple Silicon builders. 4 | 5 | GitHub Actions has introduced M1 MacOS builders and as such, we are happy to announce that ponyup again supports MacOS on Apple Silicon. 6 | 7 | -------------------------------------------------------------------------------- /.release-notes/0.8.3.md: -------------------------------------------------------------------------------- 1 | ## Add Ubuntu 24.04 support 2 | 3 | We've added support for identifying Ubuntu 24.04 and downloading packages for it. As of the time of this release, no release versions of `ponyc` are available- only nightly versions. Release versions of `ponyc` will be available once a version of `ponyc` post 0.58.3 is released. 4 | 5 | -------------------------------------------------------------------------------- /.release-notes/0.8.4.md: -------------------------------------------------------------------------------- 1 | ## Add Fedora 41 support 2 | 3 | We've added support for identifying Fedora 41 and downloading packages for it. 4 | 5 | -------------------------------------------------------------------------------- /.release-notes/0.8.5.md: -------------------------------------------------------------------------------- 1 | ## Use Alpine 3.20 as our base image 2 | 3 | Previously we were using Alpine 3.18 which has reached it's end-of-life. The change to 3.20 should have no impact on anyone unless they are using this image as the base image for another image. 4 | 5 | ## Drop Fedora 39 support 6 | 7 | Fedora 39 has reached its end of life date. We've dropped it as a supported platform for `ponyc` and `ponyup`. 8 | 9 | For `ponyup` that means, we no longer test against it when doing CI. Additinally, new installations of `ponyup` on Fedora 39 and related platforms won't recognize it as a supported package. If you install `ponyup` on such a platform, you'll need to set the platform to `fedora39` yourself. 10 | 11 | For `ponyc` the lack of support means that if you are using `ponyup` on Fedora 39 that it won't be able to install any version of `ponyc` from the point that we stopped supporting Fedora 39 for `ponyc`. Any `ponyc` from 0.58.8 on will not be able to be installed via `ponyup` and will need to instead be built from source. 12 | 13 | -------------------------------------------------------------------------------- /.release-notes/0.8.6.md: -------------------------------------------------------------------------------- 1 | ## Drop Ubuntu 20.04 support 2 | 3 | Ubuntu 20.04 has reached its end of life date. We've dropped it as a supported platform for `ponyc` and `ponyup`. 4 | 5 | For `ponyup` that means, we no longer test against it when doing CI. Additinally, new installations of `ponyup` on Ubuntu 20.04 and related platforms won't recognize it as a supported package. If you install `ponyup` on such a platform, you'll need to set the platform to `ubuntu20.04` yourself. 6 | 7 | For `ponyc` the lack of support means that if you are using `ponyup` on Ubuntu 20.04 that it won't be able to install any version of `ponyc` from the point that we stopped supporting 20.04 for `ponyc`. Any `ponyc` after 0.59.0 on will not be able to be installed via `ponyup` and will need to instead be built from source. 8 | 9 | ## Fix ponyup no longer being able to install programs by version 10 | 11 | The HTTP search interface for Cloudsmith where we store all our programs has changed. Searching by version stopped working and we were not able to install programs by version anymore. 12 | 13 | This has now been fixed by using the new search interface. You can now again install programs by version. 14 | 15 | -------------------------------------------------------------------------------- /.release-notes/next-release.md: -------------------------------------------------------------------------------- 1 | ## Add arm64 Linux builds 2 | 3 | We've added arm64 builds for Linux to our release process. 4 | 5 | ## Add Support for Alpine 3.21 on arm64 6 | 7 | We've added support for Alpine 3.21 on arm64. This means that if you are using `ponyup` on an arm64 system with Alpine 3.21, it will now recognize it as a supported platform and allow you to install `ponyc` and other related packages. 8 | 9 | ## Add Support for Alpine 3.21 on x86-64 10 | 11 | We've added support for Alpine 3.21 on x86-64. We are moving away from having generic "musl-libc" packages as they aren't guaranteed to work on all musl-libc systems unless everything is statically linked which in the case of the Pony compiler is not the case. This means that if you are using `ponyup` on an x86-64 system with Alpine 3.21, it will now recognize it as a supported platform and allow you to install `ponyc` and other related packages. 12 | 13 | ## Add Support for Alpine 3.20 on x86-64 14 | 15 | We've added support for Alpine 3.20 on x86-64. We are moving away from having generic "musl-libc" packages as they aren't guaranteed to work on all musl-libc systems unless everything is statically linked which in the case of the Pony compiler is not the case. This means that if you are using `ponyup` on an x86-64 system with Alpine 3.20, it will now recognize it as a supported platform and allow you to install `ponyc` and other related packages. 16 | 17 | ## Add Support for Ubuntu 24.04 on arm64 18 | 19 | We've added support for Ubuntu 24.04 on arm64. This means that if you are using `ponyup` on an arm64 system with Ubuntu 24.04, it will now recognize it as a supported platform and allow you to install `ponyc` and other related packages. 20 | 21 | ## Stop having a base image 22 | 23 | Previously we were using Alpine 3.20 as the base image for the ponyup container image. We've switched to using the `scratch` image instead. This means that the container image is now much smaller and only contains the `ponyup` binary. 24 | 25 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/) and [Keep a CHANGELOG](http://keepachangelog.com/). 4 | 5 | ## [unreleased] - unreleased 6 | 7 | ### Fixed 8 | 9 | 10 | ### Added 11 | 12 | - Add arm64 Linux builds ([PR #319](https://github.com/ponylang/ponyup/pull/319)) 13 | - Add Alpine 3.21 on arm64 as a supported platform ([PR #320](https://github.com/ponylang/ponyup/pull/320)) 14 | - Add Alpine 3.21 on x86-64 as a supported platform ([PR #321](https://github.com/ponylang/ponyup/pull/321)) 15 | - Add Alpine 3.20 on x86-64 as a supported platform ([PR #322](https://github.com/ponylang/ponyup/pull/322)) 16 | - Add Ubuntu 24.04 on arm64 as a supported platform ([PR #323](https://github.com/ponylang/ponyup/pull/323)) 17 | 18 | ### Changed 19 | 20 | - Stop having a base image ([PR #324](https://github.com/ponylang/ponyup/pull/324)) 21 | 22 | ## [0.8.6] - 2025-06-01 23 | 24 | ### Fixed 25 | 26 | - Fix ponyup no longer being able to install programs by version ([PR #317](https://github.com/ponylang/ponyup/pull/317)) 27 | 28 | ### Changed 29 | 30 | - Drop Ubuntu 20.04 support ([PR #315](https://github.com/ponylang/ponyup/pull/315)) 31 | 32 | ## [0.8.5] - 2024-12-27 33 | 34 | ### Changed 35 | 36 | - Use Alpine 3.20 as our base image ([PR #306](https://github.com/ponylang/ponyup/pull/306)) 37 | - Drop Fedora 39 Support ([PR #309](https://github.com/ponylang/ponyup/pull/309)) 38 | 39 | ## [0.8.4] - 2024-12-08 40 | 41 | ### Added 42 | 43 | - Add Fedora 41 Support ([PR #308](https://github.com/ponylang/ponyup/pull/308)) 44 | 45 | ## [0.8.3] - 2024-04-27 46 | 47 | ### Added 48 | 49 | - Add Ubuntu 24.04 support ([PR #303](https://github.com/ponylang/ponyup/pull/303)) 50 | 51 | ## [0.8.2] - 2024-02-02 52 | 53 | ### Added 54 | 55 | - Add MacOS on Apple Silicon as a fully supported platform ([PR #290](https://github.com/ponylang/ponyup/pull/290)) 56 | 57 | ## [0.8.1] - 2024-01-30 58 | 59 | ### Added 60 | 61 | - Add support for Fedora 39 ([PR #289](https://github.com/ponylang/ponyup/pull/289)) 62 | 63 | ### Changed 64 | 65 | - Update base image to Alpine 3.18 ([PR #268](https://github.com/ponylang/ponyup/pull/268)) 66 | 67 | ## [0.8.0] - 2023-08-30 68 | 69 | ### Added 70 | 71 | - Add macOS on Intel as a fully supported platform ([PR #257](https://github.com/ponylang/ponyup/pull/257)) 72 | 73 | ### Changed 74 | 75 | - Change supported MacOS version to Ventura ([PR #250](https://github.com/ponylang/ponyup/pull/250)) 76 | - Drop Ubuntu 18.04 support ([PR #252](https://github.com/ponylang/ponyup/pull/252)) 77 | - Drop FreeBSD support ([PR #255](https://github.com/ponylang/ponyup/pull/255)) 78 | - Temporarily drop macOS on Apple Silicon as fully supported platform ([PR #258](https://github.com/ponylang/ponyup/pull/258)) 79 | 80 | ## [0.7.0] - 2023-01-20 81 | 82 | ### Changed 83 | 84 | - Remove macOS on Intel support ([PR #240](https://github.com/ponylang/ponyup/pull/240)) 85 | - Never use the "generic gnu" ponyc package ([PR #245](https://github.com/ponylang/ponyup/pull/245)) 86 | 87 | ## [0.6.9] - 2022-12-02 88 | 89 | ### Changed 90 | 91 | - Switch supported FreeBSD to 13.1 ([PR #238](https://github.com/ponylang/ponyup/pull/238)) 92 | 93 | ## [0.6.8] - 2022-11-24 94 | 95 | ### Fixed 96 | 97 | - Fixed ponyup-init.sh crash when specifying --prefix ([PR #236](https://github.com/ponylang/ponyup/pull/236)) 98 | 99 | ### Changed 100 | 101 | - Update Alpine version used for CI to 3.16 (#229) ([PR #230](https://github.com/ponylang/ponyup/pull/230)) 102 | 103 | ## [0.6.7] - 2022-05-28 104 | 105 | ### Added 106 | 107 | - Add ARM64 support ([PR #226](https://github.com/ponylang/ponyup/pull/226)) 108 | - Add support for MacOS on Apple Silicon ([PR #228](https://github.com/ponylang/ponyup/pull/228)) 109 | 110 | ## [0.6.6] - 2022-02-11 111 | 112 | ### Added 113 | 114 | - Add Windows support ([PR #214](https://github.com/ponylang/ponyup/pull/214)) 115 | 116 | ## [0.6.5] - 2021-10-05 117 | 118 | ### Changed 119 | 120 | - Update to work with Pony 0.44.0 ([PR #194](https://github.com/ponylang/ponyup/pull/194)) 121 | 122 | ## [0.6.4] - 2021-07-05 123 | 124 | ### Changed 125 | 126 | - Switch supported FreeBSD to 13.0 ([PR #161](https://github.com/ponylang/ponyup/pull/161)) 127 | 128 | ## [0.6.3] - 2021-03-21 129 | 130 | ### Fixed 131 | 132 | - Update Linux builder image ([PR #182](https://github.com/ponylang/ponyup/pull/182)) 133 | 134 | ## [0.6.2] - 2021-03-19 135 | 136 | ### Fixed 137 | 138 | - Fix incorrect FreeBSD to Cloudsmith package mapping ([PR #162](https://github.com/ponylang/ponyup/pull/162)) 139 | - Don't prompt for libc type when not on Linux ([PR #179](https://github.com/ponylang/ponyup/pull/179)) 140 | 141 | ### Changed 142 | 143 | - Switch FreeBSD supported version to 12.2 ([PR #175](https://github.com/ponylang/ponyup/pull/175)) 144 | 145 | ## [0.6.1] - 2020-08-29 146 | 147 | ### Fixed 148 | 149 | - Incorrect initial ponyup version ([PR #151](https://github.com/ponylang/ponyup/pull/151)) 150 | - Fix ponyup-init on freebsd ([PR #156](https://github.com/ponylang/ponyup/pull/156)) 151 | 152 | ## [0.6.0] - 2020-08-20 153 | 154 | ### Changed 155 | 156 | - Use `XDG_DATA_HOME` for install prefix in init script when set ([PR #137](https://github.com/ponylang/ponyup/pull/137)) 157 | - Select uses latest version if none is specified ([PR #139](https://github.com/ponylang/ponyup/pull/139)) 158 | - Update Dockerfile to Alpine 3.12 ([PR #145](https://github.com/ponylang/ponyup/pull/145)) 159 | 160 | ## [0.5.4] - 2020-06-22 161 | 162 | ### Fixed 163 | 164 | - Fix init script default ([PR #132](https://github.com/ponylang/ponyup/pull/132)) 165 | 166 | ## [0.5.3] - 2020-06-20 167 | 168 | ### Added 169 | 170 | - Prompt user for platform libc if unspecified by target triple ([PR #128](https://github.com/ponylang/ponyup/pull/128)) 171 | - Add default command ([PR #129](https://github.com/ponylang/ponyup/pull/129)) 172 | 173 | ## [0.5.2] - 2020-05-23 174 | 175 | ### Fixed 176 | 177 | - Fix cli platform identification ([PR #112](https://github.com/ponylang/ponyup/pull/112)) 178 | 179 | ### Added 180 | 181 | - Add FreeBSD support ([PR #113](https://github.com/ponylang/ponyup/pull/113)) 182 | 183 | ### Changed 184 | 185 | - Use nightly ponyup on macOS ([PR #122](https://github.com/ponylang/ponyup/pull/122)) 186 | 187 | ## [0.5.1] - 2020-02-05 188 | 189 | ### Fixed 190 | 191 | - Include initial ponyup package in lockfile ([PR #89](https://github.com/ponylang/ponyup/pull/89)) 192 | - Use `shasum` if `sha256sum` command is missing, or exit with error message ([PR #92](https://github.com/ponylang/ponyup/pull/92)) 193 | 194 | ### Added 195 | 196 | - Colorize important ponyup-init.sh output ([PR #81](https://github.com/ponylang/ponyup/pull/81)) 197 | - Support showing `$PATH` message for [fish shell](https://fish.sh) ([PR #92](https://github.com/ponylang/ponyup/pull/92)) 198 | 199 | ## [0.5.0] - 2020-01-02 200 | 201 | ### Added 202 | 203 | - Detect platform identifier with init script ([PR #60](https://github.com/ponylang/ponyup/pull/60)) 204 | 205 | ### Changed 206 | 207 | - Use unix appdirs for macOS ([PR #69](https://github.com/ponylang/ponyup/pull/69)) 208 | 209 | ## [0.4.0] - 2019-12-27 210 | 211 | ### Added 212 | 213 | - Add macOS support ([PR #56](https://github.com/ponylang/ponyup/pull/56)) 214 | 215 | ## [0.3.1] - 2019-12-19 216 | 217 | ### Fixed 218 | 219 | - Incorrect path usage in ponyup-init.sh 220 | 221 | ## [0.3.0] - 2019-12-18 222 | 223 | ### Changed 224 | 225 | - Use platform-specific storage paths ([PR #51](https://github.com/ponylang/ponyup/pull/51)) 226 | 227 | ## [0.2.0] - 2019-11-21 228 | 229 | ### Added 230 | 231 | - Add changelog-tool package ([PR #38](https://github.com/ponylang/ponyup/pull/38)) 232 | - Add support for release channel ([PR #22](https://github.com/ponylang/ponyup/pull/22)) 233 | - Add option to specify ponyc libc 234 | - "Show" enhancements ([PR #47](https://github.com/ponylang/ponyup/pull/47)) 235 | 236 | ## [0.1.0] - 2019-08-25 237 | 238 | ### Added 239 | 240 | - Initial version for updating the nightly release of ponyc, stable, and corral 241 | 242 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at coc@ponylang.io. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | 48 | # Social Rules 49 | 50 | In addition to having a code of conduct as an anti-harassment policy, we have a small set of [social rules](https://www.recurse.com/manual#sub-sec-social-rules) we follow. We (the project maintainers) lifted these rules from the [Recurse Center](https://www.recurse.com). We've seen these rules in effect in other environments. We'd like the Pony community to share a similar positive environment. These rules are intended to be lightweight, and to make more explicit certain social norms that are normally implicit. Most of our social rules really boil down to “don't be a jerk” or “don't be annoying.” Of course, almost nobody sets out to be a jerk or annoying, so telling people not to be jerks isn't a very productive strategy. 51 | 52 | Unlike the anti-harassment policy, violation of the social rules will not result in expulsion from the Pony community or a strong warning from project maintainers. Rather, they are designed to provide some lightweight social structure for community members to use when interacting with each other. 53 | 54 | ## No feigning surprise. 55 | 56 | The first rule means you shouldn't act surprised when people say they don't know something. This applies to both technical things ("What?! I can't believe you don't know what the stack is!") and non-technical things ("You don't know who RMS is?!"). Feigning surprise has absolutely no social or educational benefit: When people feign surprise, it's usually to make them feel better about themselves and others feel worse. And even when that's not the intention, it's almost always the effect. 57 | 58 | ## No well-actually's 59 | 60 | A well-actually happens when someone says something that's almost - but not entirely - correct, and you say, "well, actually…" and then give a minor correction. This is especially annoying when the correction has no bearing on the actual conversation. This doesn't mean we aren't about truth-seeking or that we don't care about being precise. Almost all well-actually's in our experience are about grandstanding, not truth-seeking. 61 | 62 | ## No subtle -isms 63 | 64 | Our last social rule bans subtle racism, sexism, homophobia, transphobia, and other kinds of bias. This one is different from the rest, because it covers a class of behaviors instead of one very specific pattern. 65 | 66 | Subtle -isms are small things that make others feel uncomfortable, things that we all sometimes do by mistake. For example, saying "It's so easy my grandmother could do it" is a subtle -ism. Like the other three social rules, this one is often accidentally broken. Like the other three, it's not a big deal to mess up – you just apologize and move on. 67 | 68 | If you see a subtle -ism in the Pony community, you can point it out to the relevant person, either publicly or privately, or you can ask one of the project maintainers to say something. After this, we ask that all further discussion move off of public channels. If you are a third party, and you don't see what could be biased about the comment that was made, feel free to talk to the project maintainers. Please don't say, "Comment X wasn't homophobic!" Similarly, please don't pile on to someone who made a mistake. The "subtle" in "subtle -isms" means that it's probably not obvious to everyone right away what was wrong with the comment. 69 | 70 | If you have any questions about any part of the code of conduct or social rules, please feel free to reach out to any of the project maintainers. 71 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | It's good to hear that you want to contribute to Ponyup! 4 | 5 | There are a number of ways to contribute to Ponyup. As this document is a little long, feel free to jump to the section that applies to you currently: 6 | 7 | * [Feature request](#feature-request) 8 | * [Bug report](#bug-report) 9 | * [How to contribute](#how-to-contribute) 10 | * [Pull request](#pull-request) 11 | 12 | Additional notes regarding formatting: 13 | 14 | * [Documentation formatting](#documentation-formatting) 15 | * [Code formatting](#code-formatting) 16 | 17 | ## Feature request 18 | 19 | For any feature requests or enhancements to Ponyup, it is quite likely that you have to go through our [RFC process](https://github.com/ponylang/rfcs). Before opening or submitting any feature requests, please make sure you are familiar with the RFC process and follow the process as required. 20 | 21 | If you submit a pull request to implement a new feature without going through the RFC process, it may be closed with a polite request to submit an RFC first. 22 | 23 | ## Bug report 24 | 25 | First of all please [search existing issues](https://github.com/ponylang/ponyup/issues) to make sure your issue hasn't already been reported. If you cannot find a suitable issue — [create a new one](https://github.com/ponylang/ponyup/issues/new). 26 | 27 | Provide the following details: 28 | 29 | * short summary of what you was trying to achieve, 30 | * a code causing the bug, 31 | * expected result, 32 | * actual results and 33 | * environment details: at least operating system and compiler version (`ponyc -v`). 34 | 35 | If possible, try to isolate the problem and provide just enough code to demonstrate it. Add any related information which might help to fix the issue. 36 | 37 | ## How to contribute 38 | 39 | We use a fairly standard GitHub pull request workflow. If you have already contributed to a project via GitHub pull request, you can skip this section and proceed to the [specific details of what we ask for in a pull request](#pull-request). If this is your first time contributing to a project via GitHub, read on. 40 | 41 | Here is the basic GitHub workflow: 42 | 43 | 1. Fork the ponyup repo. you can do this via the GitHub website. This will result in you having your own copy of the ponyup repo under your GitHub account. 44 | 2. Clone your ponyup repo to your local machine 45 | 3. Make a branch for your change 46 | 4. Make your change on that branch 47 | 5. Push your change to your repo 48 | 6. Use the github ui to open a PR 49 | 50 | Some things to note that aren't immediately obvious to folks just starting out: 51 | 52 | 1. Your fork doesn't automatically stay up to date with change in the main repo. 53 | 2. Any changes you make on your branch that you used for the PR will automatically appear in the PR so if you have more than 1 PR, be sure to always create different branches for them. 54 | 3. Weird things happen with commit history if you don't create your PR branches off of main so always make sure you have the main branch checked out before creating a branch for a PR 55 | 56 | If you feel overwhelmed at any point, don't worry, it can be a lot to learn when you get started. Feel free to reach out via [Zulip](https://ponylang.zulipchat.com). 57 | 58 | You can get help using GitHub via [the official documentation](https://help.github.com/). Some highlights include: 59 | 60 | * [Fork A Repo](https://help.github.com/articles/fork-a-repo/) 61 | * [Creating a pull request](https://help.github.com/articles/creating-a-pull-request/) 62 | * [Syncing a fork](https://help.github.com/articles/syncing-a-fork/) 63 | 64 | ## Pull request 65 | 66 | While we don't require that your pull request be a single commit, note that we will end up squashing all your commits into a single commit when we merge. While your PR is in review, we may ask for additional changes, please do not squash those commits while the review is underway. We ask that you not squash while a review is underway as it can make it hard to follow what is going on. 67 | 68 | When opening your pull request, please make sure that the initial comment on the PR is the commit message we should use when we merge. Making sure your commit message conforms to these guidelines for [writ(ing) a good commit message](http://chris.beams.io/posts/git-commit/). 69 | 70 | Make sure to issue 1 pull request per feature. Don't lump unrelated changes together. If you find yourself using the word "and" in your commit comment, you 71 | are probably doing too much for a single PR. 72 | 73 | We keep a [CHANGELOG](CHANGELOG.md) of all software changes with behavioural effects in ponyc. If your PR includes such changes (rather than say a documentation update), a Pony team member will do the following before merging it, so that the PR will be automatically added to the CHANGELOG: 74 | 75 | * Ensure that the ticket is tagged with one or more appropriate "changelog - *" labels - each label corresponds to a section of the changelog where this change will be automatically mentioned. 76 | * Ensure that the ticket title is appropriate - the title will be used as the summary of the change, so it should be appropriately formatted, including a ticket reference if the PR is a fix to an existing bug ticket. 77 | * For example, an appropriate title for a PR that fixes a bug reported in issue ticket #98 might look like: 78 | * *Fixed compiler crash related to tuple recovery (issue #98)* 79 | 80 | Once those conditions are met, the PR can be merged, and an automated system will immediately add the entry to the changelog. Keeping the changelog entries out of the file changes in the PR helps to avoid conflicts and other administrative headaches when many PRs are in progress. 81 | 82 | Any change that involves a changelog entry will trigger a bot to request that you add release notes to your PR. 83 | 84 | Pull requests from accounts that aren't members of the Ponylang organization require approval from a member before running. Approval is required after each update that you make. This could involve a lot of waiting on your part for approvals. If you are opening PRs to verify that changes all pass CI before "opening it for real", we strongly suggest that you open the PR against the `main` branch of your fork. CI will then run in your fork and you don't need to wait for approval from a Ponylang member. 85 | 86 | ## Documentation Formatting 87 | 88 | When contributing to documentation, try to keep the following style guidelines in mind: 89 | 90 | * Wherever possible, try to match the style of surrounding documentation. 91 | * Avoid hard-wrapping lines within paragraphs (using line breaks in the middle of or between sentences to make lines shorter than a certain length). Instead, turn on soft-wrapping in your editor and expect the documentation renderer to let the text flow to the width of the container. 92 | * Apply code highlighting to identifier names, such as types, fields, variables and parameters via the customary markdown syntax of wrapping the name in backticks. 93 | 94 | ## Code Formatting 95 | 96 | For code formatting guidelines please see [The Style Guide](https://github.com/ponylang/ponyc/blob/main/STYLE_GUIDE.md). 97 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ghcr.io/ponylang/shared-docker-ci-x86-64-unknown-linux-builder-with-libressl-3.9.1:release AS build 2 | 3 | WORKDIR /src/ponyup 4 | 5 | COPY Makefile LICENSE VERSION corral.json /src/ponyup/ 6 | 7 | WORKDIR /src/ponyup/cmd 8 | 9 | COPY cmd /src/ponyup/cmd/ 10 | 11 | WORKDIR /src/ponyup 12 | 13 | RUN make arch=x86-64 static=true linker=bfd config=release 14 | 15 | FROM scratch 16 | 17 | COPY --from=build /src/ponyup/build/release/ponyup /usr/local/bin/ponyup 18 | 19 | CMD ponyup 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2019, The Pony Developers 4 | Copyright (c) 2019, Theodore Butler 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | prefix ?= /usr/local 2 | destdir ?= $(prefix) 3 | config ?= release 4 | arch ?= 5 | static ?= false 6 | linker ?= 7 | 8 | ssl ?= 0.9.0 9 | PONYC_FLAGS ?= 10 | 11 | BUILD_DIR ?= build/$(config) 12 | SRC_DIR ?= cmd 13 | binary := $(BUILD_DIR)/ponyup 14 | 15 | PONYUP_PLATFORM ?= $(shell cc -dumpmachine) 16 | 17 | ifdef config 18 | ifeq (,$(filter $(config),debug release)) 19 | $(error Unknown configuration "$(config)") 20 | endif 21 | endif 22 | 23 | ifeq ($(config),debug) 24 | PONYC_FLAGS += --debug 25 | endif 26 | 27 | ifeq ($(ssl), 3.0.x) 28 | PONYC_FLAGS += -Dopenssl_3.0.x 29 | else ifeq ($(ssl), 1.1.x) 30 | PONYC_FLAGS += -Dopenssl_1.1.x 31 | else ifeq ($(ssl), 0.9.0) 32 | PONYC_FLAGS += -Dopenssl_0.9.0 33 | else 34 | $(error Unknown SSL version "$(ssl)". Must set using 'ssl=FOO') 35 | endif 36 | 37 | ifneq ($(arch),) 38 | PONYC_FLAGS += --cpu $(arch) 39 | endif 40 | 41 | ifdef static 42 | ifeq (,$(filter $(static),true false)) 43 | $(error "static must be true or false) 44 | endif 45 | endif 46 | 47 | ifeq ($(static),true) 48 | LINKER += --static 49 | endif 50 | 51 | ifneq ($(linker),) 52 | LINKER += --link-ldcmd=$(linker) 53 | endif 54 | 55 | # Default to version from `VERSION` file but allowing overridding on the 56 | # make command line like: 57 | # make version="nightly-19710702" 58 | # overridden version *should not* contain spaces or characters that aren't 59 | # legal in filesystem path names 60 | ifndef version 61 | version := $(shell cat VERSION) 62 | ifneq ($(wildcard .git),) 63 | sha := $(shell git rev-parse --short HEAD) 64 | tag := $(version)-$(sha) 65 | else 66 | tag := $(version) 67 | endif 68 | else 69 | foo := $(shell touch VERSION) 70 | tag := $(version) 71 | endif 72 | 73 | SOURCE_FILES := $(shell find $(SRC_DIR) -path $(SRC_DIR)/test -prune -o -name \*.pony) 74 | VERSION := "$(tag) [$(config)]" 75 | GEN_FILES_IN := $(shell find $(SRC_DIR) -name \*.pony.in) 76 | GEN_FILES = $(patsubst %.pony.in, %.pony, $(GEN_FILES_IN)) 77 | 78 | %.pony: %.pony.in VERSION 79 | sed s/%%VERSION%%/$(version)/ $< > $@ 80 | 81 | $(binary): $(GEN_FILES) $(SOURCE_FILES) | $(BUILD_DIR) 82 | corral fetch 83 | corral run -- ponyc $(PONYC_FLAGS) $(LINKER) $(SRC_DIR) -o $(BUILD_DIR) -b ponyup 84 | 85 | install: $(binary) 86 | @echo "install" 87 | mkdir -p $(DESTDIR)$(prefix)/bin 88 | cp $^ $(DESTDIR)$(prefix)/bin 89 | 90 | SOURCE_FILES := $(shell find cmd -name \*.pony) 91 | 92 | test: $(binary) 93 | corral fetch 94 | corral run -- ponyc $(PONYC_FLAGS) $(LINKER) test -o $(BUILD_DIR) -b test 95 | env PONYUP_PLATFORM="${PONYUP_PLATFORM}" $(BUILD_DIR)/test --sequential 96 | 97 | clean: 98 | corral clean 99 | rm -rf $(BUILD_DIR) $(GEN_FILES) 100 | 101 | all: test $(binary) 102 | 103 | $(BUILD_DIR): 104 | mkdir -p $(BUILD_DIR) 105 | 106 | .PHONY: all clean install test 107 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ponyup 2 | 3 | The Pony toolchain multiplexer 4 | 5 | ## Status 6 | 7 | This project is currently beta software. 8 | 9 | ## Usage 10 | 11 | ### Install dependencies 12 | 13 | #### macOS 14 | 15 | ```bash 16 | brew install libressl 17 | ``` 18 | 19 | ### Install ponyup 20 | 21 | On Unix: 22 | 23 | ```bash 24 | sh -c "$(curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/ponylang/ponyup/latest-release/ponyup-init.sh)" 25 | ``` 26 | 27 | On Windows PowerShell Core: 28 | 29 | ```pwsh 30 | Invoke-WebRequest -Uri 'https://raw.githubusercontent.com/ponylang/ponyup/latest-release/ponyup-init.ps1' -Outfile ponyup-init.ps1 && &.\ponyup-init.ps1 31 | ``` 32 | 33 | On Windows Powershell: 34 | 35 | ```pwsh 36 | Invoke-WebRequest -Uri 'https://raw.githubusercontent.com/ponylang/ponyup/latest-release/ponyup-init.ps1' -Outfile ponyup-init.ps1 37 | &.\ponyup-init.ps1 38 | ``` 39 | 40 | Note that you will need to have Visual Studio 2022 or 2019 (available [here](https://www.visualstudio.com/vs/community/)) or the Microsoft C++ Build Tools (available [here](https://visualstudio.microsoft.com/visual-cpp-build-tools/)). Install the `Desktop Development with C++` workload, along with the latest `Windows 10 SDK (10.x.x.x) for Desktop` individual component. 41 | 42 | ### Install Pony 43 | 44 | Choose the latest release of the Pony compiler or the latest nightly build. 45 | 46 | ```bash 47 | ponyup update ponyc nightly 48 | ``` 49 | 50 | ```bash 51 | ponyup update ponyc release 52 | ``` 53 | 54 | These commands will download the chosen version of ponyc and install it to `$HOME/.local/share/ponyup/bin` by default. See the instructions below for how to set the install path and manage Pony applications. 55 | 56 | ### Set install prefix 57 | 58 | On Unix: 59 | 60 | By default, ponyup will create its root directory in `$HOME/.local/share`. This prefix can be set manually with the `--prefix` (or `-p`) option. All packages selected as default will be symbolically linked into `${prefix}/ponyup/bin`. So, by default, `ponyup update release ponyc` will install `ponyc` to `$HOME/.local/share/ponyup/bin/ponyc`. 61 | 62 | On Windows: 63 | 64 | By default, ponyup will create its root directory in `%LOCALAPPDATA%\ponyup`. This prefix can be set manually with the `--prefix` (or `-p`) option. ponyup will create batch file shims (e.g. `ponyc.bat` in `%LOCALAPPDATA%\ponyup\bin`) that will run the selected version. 65 | 66 | ### Install a previous package version 67 | 68 | You can install any prior release or nightly build available on [Cloudsmith](https://cloudsmith.io/~ponylang/repos/). For example, `changelog-tool` `0.4.0` can be installed with the following command: 69 | 70 | ```bash 71 | ponyup update changelog-tool release-0.4.0 72 | ``` 73 | 74 | ### Show installed package versions 75 | 76 | The `ponyup show` command will display the installed package versions with the selected packages marked as green with an asterisk. If a more recent version is not installed, then the more recent version will be shown in yellow following the selected version. 77 | 78 | ```console 79 | $ ponyup show 80 | stable-nightly-20191116 * 81 | stable-nightly-20191115 82 | ponyc-release-0.33.0-musl * 83 | ponyc-nightly-20191116-musl 84 | ponyc-nightly-20191115-musl 85 | corral-nightly-20191115 * -- corral-nightly-20191116 86 | changelog-tool-nightly-20191116 87 | changelog-tool-nightly-20191115 * 88 | ``` 89 | 90 | The `show` command also has an optional `package` argument to show only the installed versions of the given package: 91 | 92 | ```console 93 | $ ponyup show ponyc 94 | ponyc-release-0.33.0-musl * 95 | ponyc-nightly-20191116-musl 96 | ponyc-nightly-20191115-musl 97 | ``` 98 | 99 | ### Select an installed package as default 100 | 101 | The `select` command can switch which installed package version to set as default. Here is an example of switching from ponyc `release-0.33.0` to `nightly-20191116`: 102 | 103 | ```console 104 | $ ponyup show ponyc 105 | ponyc-release-0.33.0-ubuntu18.04 * 106 | ponyc-nightly-20191116-ubuntu18.04 107 | ponyc-nightly-20191115-ubuntu18.04 108 | $ ponyc --version 109 | 0.33.0-98c36095 [release] 110 | compiled with: llvm 7.0.1 -- cc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0 111 | Defaults: pic=true 112 | $ ponyup select ponyc nightly-20191116 113 | selecting ponyc-nightly-20191116-ubuntu18.04 as default for ponyc 114 | $ ponyup show ponyc 115 | ponyc-release-0.33.0-ubuntu18.04 116 | ponyc-nightly-20191116-ubuntu18.04 * 117 | ponyc-nightly-20191115-ubuntu18.04 118 | $ ponyc --version 119 | nightly-20191116 [release] 120 | compiled with: llvm 7.1.0 -- cc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0 121 | Defaults: pic=true 122 | ``` 123 | 124 | ### Platform options 125 | 126 | Ponyup is able to detect the CPU architecture and operating system of the platform on which it is running. The `--platform` option is used to override any field in the platform identifier (e.g. `x86_64-linux-ubuntu24.04`). 127 | 128 | ### Common Issues 129 | 130 | - Unable to install ponyc: 131 | 132 | ```console 133 | error: unexpected selection: ponyc-release-x86_64-unknown-linux 134 | ``` 135 | 136 | This is likely caused by a target triple that does not specify the libc ABI for the platform, as detected by `cc -dumpmachine`. The solution is to manually set the platform identifier using `ponyup default `, where `` is a platform identifier such as `x86_64-linux-ubuntu24.04`. 137 | -------------------------------------------------------------------------------- /RELEASE_PROCESS.md: -------------------------------------------------------------------------------- 1 | # How to cut a ponyup release 2 | 3 | This document is aimed at members of the team who might be cutting a release of ponyup. It serves as a checklist that can take you through doing a release step-by-step. 4 | 5 | ## Prerequisites 6 | 7 | * You must have commit access to the ponyup repository. 8 | * It would be helpful to have read and write access to the ponylang [cloudsmith](https://cloudsmith.io/) account. 9 | 10 | ## Releasing 11 | 12 | Please note that this document was written with the assumption that you are using a clone of the `ponyup` repo. You have to be using a clone rather than a fork. It is advised to your do this by making a fresh clone of the `ponyup` repo from which you will release. 13 | 14 | ```bash 15 | git clone git@github.com:ponylang/ponyup.git ponyup-release-clean 16 | cd ponyup-release-clean 17 | ``` 18 | 19 | Before getting started, you will need a number for the version that you will be releasing as well as an agreed upon "golden commit" that will form the basis of the release. 20 | 21 | The "golden commit" must be `HEAD` on the `main` branch of this repository. At this time, releasing from any other location is not supported. 22 | 23 | For the duration of this document, that we are releasing version is `0.3.1`. Any place you see those values, please substitute your own version. 24 | 25 | ```bash 26 | git tag release-0.3.1 27 | git push origin release-0.3.1 28 | ``` 29 | 30 | ## If something goes wrong 31 | 32 | The release process can be restarted at various points in it's lifecycle by pushing specially crafted tags. 33 | 34 | ## Start a release 35 | 36 | As documented above, a release is started by pushing a tag of the form `release-x.y.z`. 37 | 38 | ## Build artifacts 39 | 40 | The release process can be manually restarted from here by pushing a tag of the form `x.y.z`. The pushed tag must be on the commit to build the release artifacts from. During the normal process, that commit is the same as the one that `release-x.y.z`. 41 | 42 | ## Announce release 43 | 44 | The release process can be manually restarted from here by push a tag of the form `announce-x.y.z`. The tag must be on a commit that is after "Release x.y.z" commit that was generated during the `Start a release` portion of the process. 45 | 46 | If you need to restart from here, you will need to pull the latest updates from the ponyup repo as it will have changed and the commit you need to tag will not be available in your copy of the repo with pulling. 47 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 0.8.6 2 | -------------------------------------------------------------------------------- /cmd/cli.pony: -------------------------------------------------------------------------------- 1 | use "cli" 2 | 3 | primitive CLI 4 | fun parse( 5 | args: Array[String] box, 6 | envs: (Array[String] box | None), 7 | default_prefix: String) 8 | : (Command | (U8, String)) 9 | => 10 | try 11 | match CommandParser(_spec(default_prefix)?).parse(args, envs) 12 | | let c: Command => c 13 | | let h: CommandHelp => (0, h.help_string()) 14 | | let e: SyntaxError => (1, e.string()) 15 | end 16 | else 17 | (-1, "unable to parse command") 18 | end 19 | 20 | fun help(default_prefix: String): String => 21 | try Help.general(_spec(default_prefix)?).help_string() else "" end 22 | 23 | fun _spec(default_prefix: String): CommandSpec ? => 24 | CommandSpec.parent( 25 | "ponyup", 26 | "The Pony toolchain multiplexer", 27 | [ OptionSpec.bool( 28 | "boring", "Do not use colorful output", 'b', false) 29 | OptionSpec.string( 30 | "prefix", "Specify toolchain install prefix", 'p', default_prefix) 31 | OptionSpec.bool( 32 | "verbose", "Show extra output", 'v', false) 33 | ], 34 | [ CommandSpec.leaf( 35 | "version", 36 | "Display the ponyup version and exit")? 37 | CommandSpec.leaf( 38 | "show", 39 | "Show installed package versions", 40 | [ OptionSpec.bool( 41 | "local", "only show installed package versions", None, false) 42 | ], 43 | [ ArgSpec.string("package" where default' = "") 44 | ])? // TODO: show [] in help message 45 | CommandSpec.leaf( 46 | "update", 47 | "Install or update a package", 48 | [ OptionSpec.string( 49 | "platform", 50 | "Specify platform (such as x86_64-linux-ubuntu24.04)", 51 | None, 52 | "") 53 | ], 54 | [ ArgSpec.string("package") 55 | ArgSpec.string("version/channel") 56 | ])? 57 | CommandSpec.leaf( 58 | "select", 59 | "Select the default version for a package", 60 | [ OptionSpec.string( 61 | "platform", 62 | "Specify platform (such as x86_64-linux-ubuntu24.04)", 63 | None, 64 | "") 65 | ], 66 | [ ArgSpec.string("package") 67 | ArgSpec.string("version") 68 | ])? 69 | CommandSpec.leaf( 70 | "default", 71 | "Set the default platform (such as x86_64-linux-ubuntu24.04)", 72 | [], 73 | [ ArgSpec.string("platform") 74 | ])? 75 | ])? 76 | .> add_help("help", "Print this message and exit")? 77 | -------------------------------------------------------------------------------- /cmd/cloudsmith.pony: -------------------------------------------------------------------------------- 1 | use "json" 2 | 3 | primitive Cloudsmith 4 | fun pkg_name(pkg: Package): String iso^ => 5 | let name = pkg.string() 6 | name.replace("-nightly", "") 7 | name.replace("-release", "") 8 | name.replace("-x86_64-", "-x86-64-") 9 | name.replace("-linux", "-unknown-linux") 10 | name.replace("-darwin", "-apple-darwin") 11 | name.replace("-windows", "-pc-windows") 12 | name 13 | 14 | fun repo_url(repo': String): String => 15 | let repo_name = 16 | match consume repo' 17 | | "nightly" => "nightlies" 18 | | "release" => "releases" 19 | | let s: String => s 20 | end 21 | "".join( 22 | [ "https://api.cloudsmith.io/packages/ponylang/"; repo_name; "/" 23 | ].values()) 24 | 25 | fun query(pkg: Package): String => 26 | let pkg_str = pkg_name(pkg) 27 | pkg_str.replace("-" + pkg.version + "-", "%20") 28 | if pkg.version != "latest" then pkg_str.append("%20version:" + pkg.version) end 29 | "".join( 30 | [ "?query="; consume pkg_str 31 | "%20status:completed" 32 | "&page=1&page_size=1" 33 | ].values()) 34 | -------------------------------------------------------------------------------- /cmd/http_handlers.pony: -------------------------------------------------------------------------------- 1 | use "collections" 2 | use "crypto" 3 | use "files" 4 | use "http" 5 | use "json" 6 | use "net" 7 | 8 | class val HTTPGet 9 | let _auth: NetAuth 10 | let _notify: PonyupNotify 11 | 12 | new val create(auth: NetAuth, notify: PonyupNotify) => 13 | _auth = auth 14 | _notify = notify 15 | 16 | fun apply(url_string: String, hf: HandlerFactory val) => 17 | let client = HTTPClient(TCPConnectAuth(_auth), hf where keepalive_timeout_secs = 10) 18 | let url = 19 | try 20 | URL.valid(url_string)? 21 | else 22 | _notify.log(InternalErr, "invalid url: " + url_string) 23 | return 24 | end 25 | 26 | let req = Payload.request("GET", url) 27 | req("User-Agent") = "ponyup" 28 | try 29 | client(consume req)? 30 | else 31 | _notify.log(Err, "server unreachable, please try again later") 32 | end 33 | 34 | class QueryHandler is HTTPHandler 35 | let _notify: PonyupNotify 36 | var _buf: String iso = recover String end 37 | let _cb: {(Array[JsonObject val] iso)} val 38 | 39 | new create(notify: PonyupNotify, cb: {(Array[JsonObject val] iso)} val) => 40 | _notify = notify 41 | _cb = cb 42 | 43 | fun ref apply(res: Payload val) => 44 | try 45 | let body' = recover String(res.body_size() as USize) end 46 | if (res.body_size() as USize) == 0 then return end 47 | for c in res.body()?.values() do chunk(c) end 48 | consume body' 49 | finished() 50 | end 51 | 52 | fun ref chunk(data: (String | Array[U8] val)) => 53 | match data 54 | | let s: String => _buf.append(s) 55 | | let bs: Array[U8] val => _buf.append(String.from_array(bs)) 56 | end 57 | 58 | fun ref finished() => 59 | _notify.log(Extra, "received response of size " + _buf.size().string()) 60 | let json_doc = recover trn JsonDoc end 61 | let result = recover Array[JsonObject val] end 62 | try 63 | json_doc.parse(_buf = recover String end)? 64 | for v in ((consume val json_doc).data as JsonArray val).data.values() do 65 | result.push(v as JsonObject val) 66 | end 67 | end 68 | _cb(consume result) 69 | 70 | fun failed( 71 | reason: (AuthFailed val | ConnectionClosed val | ConnectFailed val)) 72 | => 73 | _notify.log(Err, "server unreachable, please try again later") 74 | 75 | class DLHandler is HTTPHandler 76 | let _dl_dump: DLDump 77 | new create(dl_dump: DLDump) => _dl_dump = dl_dump 78 | fun apply(res: Payload val) => _dl_dump(res) 79 | fun chunk(bs: ByteSeq val) => _dl_dump.chunk(bs) 80 | fun finished() => _dl_dump.finished() 81 | 82 | actor DLDump 83 | let _notify: PonyupNotify 84 | let _file_path: FilePath 85 | let _cb: {(String)} val 86 | let _file_name: String 87 | let _file: File 88 | let _digest: Digest = Digest.sha512() 89 | var _total: USize = 0 90 | var _progress: USize = 0 91 | var _percent: USize = 0 92 | 93 | new create(notify: PonyupNotify, file_path: FilePath, cb: {(String)} val) => 94 | _notify = consume notify 95 | _file_path = consume file_path 96 | _cb = consume cb 97 | 98 | let components = _file_path.path.split("/") 99 | _file_name = try components(components.size() - 1)? else "" end 100 | _file = File(_file_path) 101 | 102 | be apply(res: Payload val) => 103 | _total = 104 | try res.headers()("Content-Length")?.usize()? else 0 end 105 | 106 | be chunk(bs: ByteSeq val) => 107 | _progress = _progress + bs.size() 108 | let percent = ((_progress.f64() / _total.f64()) * 100).usize() 109 | if percent > _percent then 110 | let progress_bar = recover String end 111 | progress_bar.append("\r |") 112 | for i in Range(0, 100, 2) do 113 | progress_bar.append(if i <= percent then "#" else "-" end) 114 | end 115 | progress_bar .> append("| ") .> append(_file_name) 116 | _notify.write(consume progress_bar) 117 | _percent = percent 118 | end 119 | 120 | _file.write(bs) 121 | try _digest.append(bs)? end 122 | 123 | be finished() => 124 | _file.dispose() 125 | _notify.write("\n") 126 | _cb(ToHexString(_digest.final())) 127 | -------------------------------------------------------------------------------- /cmd/main.pony: -------------------------------------------------------------------------------- 1 | use "appdirs" 2 | use "cli" 3 | use "files" 4 | use "term" 5 | 6 | actor Main is PonyupNotify 7 | let _env: Env 8 | let _default_root: String 9 | var _verbose: Bool = false 10 | var _boring: Bool = false 11 | 12 | new create(env: Env) => 13 | _env = consume env 14 | 15 | let app_dirs = 16 | recover val AppDirs(_env.vars, "ponyup" where osx_as_unix = true) end 17 | _default_root = try app_dirs.user_data_dir()? else "" end 18 | if _default_root == "" then 19 | _env.out.print("error: Unable to find user data directory") 20 | return 21 | end 22 | 23 | run_command(_env.root) 24 | 25 | be run_command(auth: AmbientAuth) => 26 | let default_prefix: String val = 27 | _default_root.substring(0, -"/ponyup".size().isize()) 28 | let command = 29 | match recover val CLI.parse(_env.args, _env.vars, default_prefix) end 30 | | let c: Command val => c 31 | | (let exit_code: U8, let msg: String) => 32 | if exit_code == 0 then 33 | _env.out.print(msg) 34 | else 35 | log(Err, msg + "\n") 36 | _env.out.print(CLI.help(default_prefix)) 37 | _env.exitcode(exit_code.i32()) 38 | end 39 | return 40 | end 41 | 42 | _verbose = command.option("verbose").bool() 43 | _boring = command.option("boring").bool() 44 | 45 | var prefix = command.option("prefix").string() 46 | if prefix == "" then prefix = default_prefix end 47 | log(Extra, "prefix: " + prefix) 48 | 49 | let ponyup_dir = FilePath(FileAuth(auth), prefix + "/ponyup") 50 | 51 | if (not ponyup_dir.exists()) and (not ponyup_dir.mkdir()) then 52 | log(Err, "unable to create root directory: " + ponyup_dir.path) 53 | end 54 | 55 | let lockfile = 56 | try 57 | recover CreateFile(ponyup_dir.join(".lock")?) as File end 58 | else 59 | log(Err, "unable to create lockfile (" + ponyup_dir.path + "/.lock)") 60 | return 61 | end 62 | 63 | var platform = command.option("platform").string() 64 | if platform == "" then 65 | try 66 | with f = OpenFile(ponyup_dir.join(".platform")?) as File do 67 | platform = f.lines().next()? .> lstrip() .> rstrip() 68 | end 69 | else 70 | log( 71 | Err, 72 | "unable to determine platform (" + ponyup_dir.path + "/.platform)") 73 | return 74 | end 75 | end 76 | log(Extra, "platform: " + platform) 77 | 78 | let ponyup = Ponyup(_env, auth, ponyup_dir, consume lockfile, this) 79 | 80 | match command.fullname() 81 | | "ponyup/version" => _env.out .> write("ponyup ") .> print(Version()) 82 | | "ponyup/show" => show(ponyup, command, platform) 83 | | "ponyup/update" => sync(ponyup, command, platform) 84 | | "ponyup/select" => select(ponyup, command, platform) 85 | | "ponyup/default" => default(ponyup, command, ponyup_dir) 86 | else 87 | log(InternalErr, "Unknown command: " + command.fullname()) 88 | end 89 | 90 | be show(ponyup: Ponyup, command: Command val, platform: String) => 91 | ponyup.show( 92 | command.arg("package").string(), 93 | command.option("local").bool(), 94 | platform) 95 | 96 | be sync(ponyup: Ponyup, command: Command val, platform: String) => 97 | let chan = command.arg("version/channel").string().split("-") 98 | let pkg = 99 | try 100 | Packages.from_fragments( 101 | command.arg("package").string(), 102 | chan(0)?, 103 | try chan(1)? else "latest" end, 104 | platform.string().split("-"))? 105 | else 106 | log(Err, "".join( 107 | [ "unexpected selection: " 108 | command.arg("package").string() 109 | "-"; command.arg("version/channel").string() 110 | "-"; platform 111 | ].values())) 112 | return 113 | end 114 | ponyup.sync(pkg) 115 | 116 | be select(ponyup: Ponyup, command: Command val, platform: String) => 117 | let chan = command.arg("version").string().split("-") 118 | let pkg = 119 | try 120 | Packages.from_fragments( 121 | command.arg("package").string(), 122 | chan(0)?, 123 | try chan(1)? else "latest" end, 124 | platform.string().split("-"))? 125 | else 126 | log(Err, "".join( 127 | [ "unexpected selection: " 128 | command.arg("package").string() 129 | "-"; command.arg("version").string() 130 | "-"; platform 131 | ].values())) 132 | return 133 | end 134 | ponyup.select(pkg) 135 | 136 | be default(ponyup: Ponyup, command: Command val, ponyup_dir: FilePath) => 137 | let platform = command.arg("platform").string() 138 | try 139 | Packages.from_fragments("", "", "", platform.split("-"))? 140 | else 141 | log(Err, "invalid platform identifier: " + platform) 142 | return 143 | end 144 | try 145 | with f = CreateFile(ponyup_dir.join(".platform")?) as File do 146 | f .> set_length(0) .> print(platform) .> flush() 147 | end 148 | end 149 | 150 | be log(level: LogLevel, msg: String) => 151 | match level 152 | | Info | Extra => 153 | if (level is Info) or _verbose then 154 | if level is Extra then 155 | _env.out.write(colorful(ANSI.grey(), "info: ")) 156 | end 157 | _env.out.print(msg) 158 | end 159 | | Err | InternalErr => 160 | _env.exitcode(1) 161 | var msg' = 162 | // strip error prefix from CLI package 163 | if msg.substring(0, 7) == "Error: " then 164 | msg.substring(7) 165 | else 166 | consume msg 167 | end 168 | _env.out .> write(colorful(ANSI.bright_red(), "error: ")) .> print(msg') 169 | 170 | if level is InternalErr then 171 | _env.out 172 | .> write("Internal error encountered. Please open an issue at ") 173 | .> print("https://github.com/ponylang/ponyup") 174 | end 175 | end 176 | 177 | be write(str: String, ansi_color_code: String = "") => 178 | _env.out.write( 179 | if ansi_color_code == "" then str else colorful(ansi_color_code, str) end) 180 | 181 | fun colorful(ansi_color_code: String, msg: String): String iso^ => 182 | "".join( 183 | [ if not _boring then ansi_color_code else "" end 184 | msg 185 | if not _boring then ANSI.reset() else "" end 186 | ].values()) 187 | 188 | fun @runtime_override_defaults(rto: RuntimeOptions) => 189 | rto.ponynoblock = true 190 | 191 | primitive Info 192 | primitive Extra 193 | primitive Err 194 | primitive InternalErr 195 | type LogLevel is (InternalErr | Err | Info | Extra) 196 | -------------------------------------------------------------------------------- /cmd/packages.pony: -------------------------------------------------------------------------------- 1 | 2 | primitive Packages 3 | fun apply(): Array[String] box => 4 | ifdef windows then 5 | ["corral"; "ponyc"; "ponyup"] 6 | else 7 | ["changelog-tool"; "corral"; "ponyc"; "ponyup"; "stable"] 8 | end 9 | 10 | fun from_fragments( 11 | name: String, 12 | channel: String, 13 | version: String, 14 | platform: Array[String] box) 15 | : Package ? 16 | => 17 | """ 18 | Parse the target indentifier fields extracted from a target triple. 19 | 20 | It is assumed that Arch field does not contain a `-` character, such as 21 | x86-64 which must be replaced by either x86_64, x64, or amd64. Vendor fields 22 | (unknown, pc, apple, etc.) are ignored. ABI fields are used to detect the 23 | libc implementation (glibc or musl) or distribution (ubuntu24.04) on 24 | Linux-based platforms. Such ABI fields are required for Linux for some 25 | packages, such as ponyc. 26 | 27 | See also https://clang.llvm.org/docs/CrossCompilation.html#target-triple 28 | """ 29 | let platform' = (consume platform).clone() 30 | // ignore vendor identifier in full target triple 31 | if platform'.size() > 3 then 32 | platform'.trim_in_place(0, 4) 33 | try platform'.delete(1)? end 34 | end 35 | var cpu: CPU = AMD64 36 | var os: OS = platform_os()? 37 | var distro: Distro = None 38 | for (i, field) in platform'.pairs() do 39 | match field 40 | | "x86_64" | "x64" | "amd64" => cpu = AMD64 41 | | "arm64" => cpu = ARM64 42 | | "linux" => os = Linux 43 | | "darwin" => os = Darwin 44 | | "windows" => os = Windows 45 | else 46 | if i == (platform'.size() - 1) then distro = field end 47 | end 48 | end 49 | if (name == "ponyc") and platform_requires_distro(os) then 50 | if distro is None then error end 51 | else 52 | distro = None 53 | end 54 | Package._create(name, channel, version, (cpu, os, distro)) 55 | 56 | fun from_string(str: String): Package ? => 57 | let fragments = str.split("-") 58 | match (fragments(0)?, fragments(1)?) 59 | | ("changelog", "tool") => 60 | fragments.delete(1)? 61 | fragments(0)? = "changelog-tool" 62 | end 63 | from_fragments( 64 | fragments(0)?, 65 | fragments(1)?, 66 | fragments(2)?, 67 | (consume fragments).slice(3))? 68 | 69 | fun platform_os(): OS ? => 70 | if Platform.osx() then Darwin 71 | elseif Platform.linux() then Linux 72 | elseif Platform.windows() then Windows 73 | else error 74 | end 75 | 76 | fun platform_distro(distro: String): Distro => 77 | if Platform.linux() then distro end 78 | 79 | fun platform_requires_distro(os: OS): Bool => 80 | match os 81 | | Linux => true 82 | | Darwin => false 83 | | Windows => false 84 | end 85 | 86 | class val Package is Comparable[Package box] 87 | let name: String 88 | let channel: String 89 | let version: String 90 | let cpu: CPU 91 | let os: OS 92 | let distro: Distro 93 | let selected: Bool 94 | 95 | new val _create( 96 | name': String, 97 | channel': String, 98 | version': String, 99 | platform': (CPU, OS, Distro), 100 | selected': Bool = false) 101 | => 102 | name = name' 103 | channel = channel' 104 | version = version' 105 | (cpu, os, distro) = platform' 106 | selected = selected' 107 | 108 | fun update_version(version': String, selected': Bool = false): Package => 109 | _create(name, channel, version', (cpu, os, distro), selected') 110 | 111 | fun platform(): String iso^ => 112 | let str = "-".join([cpu; os].values()) 113 | match (name == "ponyc", distro) 114 | | (true, let distro_name: String) => str.append("-" + distro_name) 115 | end 116 | str 117 | 118 | fun eq(other: Package box): Bool => 119 | string() == other.string() 120 | 121 | fun lt(other: Package box): Bool => 122 | string() <= other.string() 123 | 124 | fun string(): String iso^ => 125 | "-".join([name; channel; version; platform()].values()) 126 | 127 | type CPU is ((AMD64 | ARM64) & _CPU) 128 | interface val _CPU is (Equatable[_OS] & Stringable) 129 | primitive AMD64 is _OS 130 | fun string(): String iso^ => "x86_64".string() 131 | primitive ARM64 is _OS 132 | fun string(): String iso^ => "arm64".string() 133 | 134 | type OS is ((Linux | Darwin | Windows) & _OS) 135 | interface val _OS is (Equatable[_OS] & Stringable) 136 | primitive Linux is _OS 137 | fun string(): String iso^ => "linux".string() 138 | primitive Darwin is _OS 139 | fun string(): String iso^ => "darwin".string() 140 | primitive Windows is _OS 141 | fun string(): String iso^ => "windows".string() 142 | 143 | type Distro is (None | String) 144 | -------------------------------------------------------------------------------- /cmd/ponyup.pony: -------------------------------------------------------------------------------- 1 | use "backpressure" 2 | use "collections" 3 | use "files" 4 | use "http" 5 | use "json" 6 | use "net" 7 | use "process" 8 | use "term" 9 | use "time" 10 | 11 | /* 12 | Main Ponyup HTTPSession ProcessMonitor 13 | | sync | | | 14 | | -------> | (HTTPGet) | | 15 | | | ----------------> | | 16 | | | query_response | | 17 | | | <---------------- | | 18 | | | (HTTPGet) | | 19 | | | ----------------> | | 20 | | | dl_complete | | 21 | | | <---------------- | | 22 | | | (extract_archive) | 23 | | | -----------------------------------> | 24 | | | extract_complete | 25 | | | <----------------------------------- | 26 | | | select | | 27 | | | - - - -. | | 28 | | | <- - - ' | | 29 | */ 30 | 31 | actor Ponyup 32 | let _notify: PonyupNotify 33 | let _env: Env 34 | let _auth: AmbientAuth 35 | let _root: FilePath 36 | let _lockfile: LockFile 37 | let _http_get: HTTPGet 38 | 39 | new create( 40 | env: Env, 41 | auth: AmbientAuth, 42 | root: FilePath, 43 | lockfile: File iso, 44 | notify: PonyupNotify) 45 | => 46 | _notify = notify 47 | _env = env 48 | _auth = auth 49 | _root = root 50 | _lockfile = LockFile(consume lockfile) 51 | _http_get = HTTPGet(NetAuth(_auth), _notify) 52 | 53 | be sync(pkg: Package) => 54 | try 55 | _lockfile.parse()? 56 | else 57 | _notify.log(Err, _lockfile.corrupt()) 58 | return 59 | end 60 | 61 | if not Packages().contains(pkg.name, {(a, b) => a == b }) then 62 | _notify.log(Err, "unknown package: " + pkg.name) 63 | return 64 | end 65 | 66 | if _lockfile.contains(pkg) then 67 | _notify.log(Info, pkg.string() + " is up to date") 68 | return 69 | end 70 | 71 | _notify.log(Info, "updating " + pkg.string()) 72 | let src_url = Cloudsmith.repo_url(pkg.channel) 73 | _notify.log(Info, "syncing updates from " + src_url) 74 | let query_string = recover val src_url + Cloudsmith.query(pkg) end 75 | _notify.log(Extra, "query url: " + query_string) 76 | 77 | _http_get( 78 | query_string, 79 | {(_)(self = recover tag this end, pkg) => 80 | QueryHandler(_notify, {(res) => self.query_response(pkg, consume res) }) 81 | }) 82 | 83 | be query_response(pkg: Package, res: Array[JsonObject val] iso) => 84 | (let version, let checksum, let download_url) = 85 | try 86 | res(0)? 87 | ( res(0)?.data("version")? as String 88 | , res(0)?.data("checksum_sha512")? as String 89 | , res(0)?.data("cdn_url")? as String ) 90 | else 91 | _notify.log(Err, "".join( 92 | [ "requested package, "; pkg; ", was not found" 93 | ].values())) 94 | return 95 | end 96 | 97 | let pkg' = (consume pkg).update_version(version) 98 | let pkg_str: String val = pkg'.string() 99 | 100 | if _lockfile.contains(pkg') then 101 | _notify.log(Info, pkg_str + " is up to date") 102 | return 103 | end 104 | 105 | (let install_path, let dl_path) = 106 | try 107 | let p = _root.join(pkg_str)? 108 | let pkg_path = 109 | recover val 110 | ifdef windows then 111 | p.path + ".zip" 112 | else 113 | p.path + ".tar.gz" 114 | end 115 | end 116 | (p, FilePath(FileAuth(_auth), pkg_path)) 117 | else 118 | _notify.log(Err, "invalid path: " + _root.path + "/" + pkg'.string()) 119 | return 120 | end 121 | _notify.log(Info, "pulling " + pkg'.string()) 122 | _notify.log(Extra, "download url: " + download_url) 123 | _notify.log(Extra, "install path: " + install_path.path) 124 | 125 | if (not _root.exists()) and (not _root.mkdir()) then 126 | _notify.log(Err, "unable to create directory: " + _root.path) 127 | return 128 | end 129 | 130 | let dump = DLDump( 131 | _notify, 132 | dl_path, 133 | {(checksum')(self = recover tag this end) => 134 | self.dl_complete(pkg', install_path, dl_path, checksum, checksum') 135 | }) 136 | 137 | _http_get(download_url, {(_)(dump) => DLHandler(dump) }) 138 | 139 | be dl_complete( 140 | pkg: Package, 141 | install_path: FilePath, 142 | dl_path: FilePath, 143 | server_checksum: String, 144 | client_checksum: String) 145 | => 146 | if client_checksum != server_checksum then 147 | _notify.log(Err, "checksum failed") 148 | _notify.log(Info, " expected: " + server_checksum) 149 | _notify.log(Info, " calculated: " + client_checksum) 150 | if not dl_path.remove() then 151 | _notify.log(Err, "unable to remove file: " + dl_path.path) 152 | end 153 | return 154 | end 155 | _notify.log(Extra, "checksum ok: " + client_checksum) 156 | 157 | install_path.mkdir() 158 | extract_archive(pkg, dl_path, install_path) 159 | 160 | be extract_complete( 161 | pkg: Package, 162 | dl_path: FilePath, 163 | install_path: FilePath) 164 | => 165 | dl_path.remove() 166 | _lockfile.add_package(pkg) 167 | select(pkg) 168 | 169 | be select(pkg: Package) => 170 | try 171 | _lockfile.parse()? 172 | else 173 | _notify.log(Err, _lockfile.corrupt()) 174 | return 175 | end 176 | 177 | _notify.log(Info, " ".join( 178 | [ "selecting"; pkg; "as default for"; pkg.name 179 | ].values())) 180 | 181 | var pkg' = 182 | try 183 | var p = pkg 184 | if p.version == "latest" then 185 | var latest = "" 186 | for installed in local_packages(p.name).values() do 187 | if (installed.channel == p.channel) and (installed.version > latest) 188 | then latest = installed.version 189 | end 190 | end 191 | _notify.log( 192 | Info, "selecting latest version: " + p.channel + "-" + latest) 193 | p = pkg.update_version(latest) 194 | end 195 | if p.version == "" then error end 196 | _lockfile.select(p)? 197 | p 198 | else 199 | _notify.log(Err, 200 | "cannot select package " + pkg.string() + ", try installing it first") 201 | return 202 | end 203 | consume pkg 204 | 205 | let pkg_dir = 206 | try 207 | _root.join(pkg'.string())? 208 | else 209 | _notify.log(InternalErr, "") 210 | return 211 | end 212 | 213 | ifdef windows then 214 | let link_rel: String = Path.sep().join(["bin"; pkg'.name].values()) 215 | + ".exe" 216 | let bin_rel: String = Path.sep().join([pkg'.string(); link_rel].values()) 217 | 218 | try 219 | let bin_path = _root.join(bin_rel)? 220 | _notify.log(Info, " bin: " + bin_path.path) 221 | 222 | let link_dir = _root.join("bin")? 223 | if not link_dir.exists() then link_dir.mkdir() end 224 | 225 | let link_path = link_dir.join(pkg'.name + ".bat")? 226 | _notify.log(Info, "link: " + link_path.path) 227 | 228 | if link_path.exists() then link_path.remove() end 229 | with file = File.create(link_path) do 230 | file.print("@echo off") 231 | file.print("\"" + bin_path.path + "\" %*") 232 | end 233 | else 234 | _notify.log(Err, "failed to create link batch file") 235 | end 236 | 237 | else 238 | let link_rel: String = "/".join(["bin"; pkg'.name].values()) 239 | let bin_rel: String = "/".join([pkg'.string(); link_rel].values()) 240 | 241 | try 242 | let bin_path = _root.join(bin_rel)? 243 | _notify.log(Info, " bin: " + bin_path.path) 244 | 245 | let link_dir = _root.join("bin")? 246 | if not link_dir.exists() then link_dir.mkdir() end 247 | 248 | let link_path = link_dir.join(pkg'.name)? 249 | _notify.log(Info, "link: " + link_path.path) 250 | 251 | if link_path.exists() then link_path.remove() end 252 | if not bin_path.symlink(link_path) then error end 253 | else 254 | _notify.log(Err, "failed to create symbolic link") 255 | return 256 | end 257 | end 258 | 259 | _lockfile.dispose() 260 | 261 | be show(package_name: String, local: Bool, platform: String) => 262 | try 263 | _lockfile.parse()? 264 | else 265 | _notify.log(Err, _lockfile.corrupt()) 266 | return 267 | end 268 | 269 | let timeout: U64 = if not local then 5_000_000_000 else 0 end 270 | ShowPackages( 271 | _notify, _http_get, platform, local_packages(package_name), timeout) 272 | 273 | fun local_packages(package_name: String): Array[Package] iso^ => 274 | let starts_with = 275 | {(p: String, s: String): Bool => s.substring(0, p.size().isize()) == p } 276 | let packages = recover Array[Package] end 277 | for pkg in _lockfile.string().split("\n").values() do 278 | if (pkg != "") and not starts_with(package_name, pkg) then continue end 279 | let frags = pkg.split(" ") 280 | try 281 | let p = Packages.from_string(frags(0)?)? 282 | let selected = (frags.size() > 1) and (frags(1)? != "") 283 | packages.push(p.update_version(p.version, selected)) 284 | end 285 | end 286 | packages 287 | 288 | fun ref extract_archive( 289 | pkg: Package, 290 | src_path: FilePath, 291 | dest_path: FilePath) 292 | => 293 | ifdef windows then 294 | _extract_archive_windows(pkg, src_path, dest_path) 295 | else 296 | _extract_archive_posix(pkg, src_path, dest_path) 297 | end 298 | 299 | fun ref _extract_archive_windows(pkg: Package, src_path: FilePath, 300 | dest_path: FilePath) 301 | => 302 | (let pwsh, let pwsh_path) = 303 | try 304 | find_pwsh(_env.vars)? 305 | else 306 | _notify.log(Err, "unable to find powershell") 307 | return 308 | end 309 | 310 | let command = recover val 311 | "\"Expand-Archive -Force -Path '" + src_path.path 312 | + "' -DestinationPath '" + dest_path.path + "'\"" 313 | end 314 | 315 | let expand_monitor = ProcessMonitor(StartProcessAuth(_auth), ApplyReleaseBackpressureAuth(_auth), 316 | object iso is ProcessNotify 317 | let self: Ponyup = this 318 | 319 | fun stdout(p: ProcessMonitor, data: Array[U8] iso) => 320 | _notify.log(Info, String.from_array(consume data)) 321 | 322 | fun stderr(p: ProcessMonitor, data: Array[U8] iso) => 323 | _notify.log(Err, String.from_array(consume data)) 324 | 325 | fun failed(p: ProcessMonitor, err: ProcessError) => 326 | _notify.log(Err, "failed to extract archive") 327 | 328 | fun dispose(p: ProcessMonitor, exit: ProcessExitStatus) => 329 | if exit != Exited(0) then 330 | _notify.log(Err, "failed to extract archive") 331 | else 332 | self.extract_complete(pkg, src_path, dest_path) 333 | end 334 | end, 335 | pwsh_path, 336 | [ pwsh 337 | "-Command" 338 | command 339 | ], 340 | _env.vars) 341 | expand_monitor.done_writing() 342 | 343 | fun ref _extract_archive_posix(pkg: Package, src_path: FilePath, 344 | dest_path: FilePath) 345 | => 346 | let tar_path = 347 | try 348 | find_tar()? 349 | else 350 | _notify.log(Err, "unable to find tar executable") 351 | return 352 | end 353 | 354 | let tar_monitor = ProcessMonitor( 355 | StartProcessAuth(_auth), 356 | ApplyReleaseBackpressureAuth(_auth), 357 | object iso is ProcessNotify 358 | let self: Ponyup = this 359 | 360 | fun failed(p: ProcessMonitor, err: ProcessError) => 361 | _notify.log(Err, "failed to extract archive") 362 | 363 | fun dispose(p: ProcessMonitor, exit: ProcessExitStatus) => 364 | if exit != Exited(0) then 365 | _notify.log(Err, "failed to extract archive") 366 | return 367 | end 368 | self.extract_complete(pkg, src_path, dest_path) 369 | end, 370 | tar_path, 371 | [ "tar"; "-xzf"; src_path.path 372 | "-C"; dest_path.path; "--strip-components"; "1" 373 | ], 374 | _env.vars) 375 | 376 | tar_monitor.done_writing() 377 | 378 | fun find_tar(): FilePath ? => 379 | for p in ["/usr/bin/tar"; "/bin/tar"].values() do 380 | let p' = FilePath(FileAuth(_auth), p) 381 | if p'.exists() then return p' end 382 | end 383 | error 384 | 385 | fun find_pwsh(vars: Array[String] val): (String, FilePath) ? => 386 | for ev in vars.values() do 387 | if ev.substring(0, 5).upper() == "PATH=" then 388 | let paths = recover val ev.substring(5).split(Path.list_sep()) end 389 | for shell in [ "pwsh.exe"; "powershell.exe" ].values() do 390 | for path in paths.values() do 391 | let fp = FilePath(FileAuth(_auth), path) 392 | try 393 | let sp = fp.join(shell)? 394 | if sp.exists() then 395 | return (shell, sp) 396 | end 397 | end 398 | end 399 | end 400 | break 401 | end 402 | end 403 | error 404 | 405 | class LockFileEntry 406 | embed packages: Array[Package] = [] 407 | var selection: USize = -1 408 | 409 | fun string(): String iso^ => 410 | let str = recover String end 411 | for (i, p) in packages.pairs() do 412 | str 413 | .> append(" ".join( 414 | [ p; if i == selection then "*" else "" end 415 | ].values())) 416 | .> append("\n") 417 | end 418 | str 419 | 420 | class LockFile 421 | let _file: File 422 | embed _entries: Map[String, LockFileEntry] = Map[String, LockFileEntry] 423 | 424 | new create(file: File) => 425 | _file = file 426 | 427 | fun ref parse() ? => 428 | if _entries.size() > 0 then return end 429 | for line in _file.lines() do 430 | let fields = line.split(" ") 431 | if fields.size() == 0 then continue end 432 | let pkg = Packages.from_string(fields(0)?)? 433 | let selected = try fields(1)? == "*" else false end 434 | 435 | let entry = _entries.get_or_else(pkg.name, LockFileEntry) 436 | if selected then 437 | entry.selection = entry.packages.size() 438 | end 439 | entry.packages.push(pkg) 440 | _entries(pkg.name) = entry 441 | end 442 | 443 | fun contains(pkg: Package): Bool => 444 | if pkg.version == "latest" then return false end 445 | let entry = _entries.get_or_else(pkg.name, LockFileEntry) 446 | entry.packages.contains(pkg, {(a, b) => a.string() == b.string() }) 447 | 448 | fun selection(pkg_name: String): (Package | None) => 449 | try 450 | let entry = _entries(pkg_name)? 451 | entry.packages(entry.selection)? 452 | end 453 | 454 | fun ref add_package(pkg: Package) => 455 | let entry = _entries.get_or_else(pkg.name, LockFileEntry) 456 | entry.packages.push(pkg) 457 | _entries(pkg.name) = entry 458 | 459 | fun ref select(pkg: Package) ? => 460 | let entry = _entries(pkg.name)? 461 | entry.selection = entry.packages.find( 462 | pkg where predicate = {(a, b) => a.string() == b.string() })? 463 | 464 | fun corrupt(): String iso^ => 465 | "".join( 466 | [ "corrupt lockfile (" 467 | _file.path.path 468 | ") please delete this file and retry" 469 | ].values()) 470 | 471 | fun string(): String iso^ => 472 | "".join(_entries.values()) 473 | 474 | fun ref dispose() => 475 | _file.set_length(0) 476 | _file.print(string()) 477 | 478 | actor ShowPackages 479 | let _notify: PonyupNotify 480 | let _http_get: HTTPGet 481 | let _local: Array[Package] 482 | embed _latest: Array[Package] = [] 483 | let _timers: Timers = Timers 484 | let _timer: Timer tag 485 | 486 | new create( 487 | notify: PonyupNotify, 488 | http_get: HTTPGet, 489 | platform: String, 490 | local: Array[Package] iso, 491 | timeout: U64) 492 | => 493 | _notify = notify 494 | _http_get = http_get 495 | _local = consume local 496 | 497 | let timer = Timer( 498 | object iso is TimerNotify 499 | let self: ShowPackages = this 500 | var fired: Bool = false 501 | 502 | fun ref apply(timer: Timer, count: U64): Bool => 503 | if not (fired = true) then self.complete() end 504 | false 505 | 506 | fun ref cancel(timer: Timer) => 507 | if not (fired = true) then self.complete() end 508 | end, 509 | timeout) 510 | _timer = recover tag timer end 511 | _timers(consume timer) 512 | 513 | if timeout == 0 then return end 514 | 515 | for channel in ["nightly"; "release"].values() do 516 | for name in Packages().values() do 517 | try 518 | let target = recover val platform.split("-") end 519 | let pkg = Packages.from_fragments(name, channel, "latest", target)? 520 | let query_str = recover val Cloudsmith.repo_url(channel) + Cloudsmith.query(pkg) end 521 | _notify.log(Extra, "query url: " + query_str) 522 | _http_get( 523 | query_str, 524 | {(_)(self = recover tag this end, channel, pkg) => 525 | QueryHandler( 526 | _notify, 527 | {(res) => 528 | try 529 | let version = (consume res)(0)?.data("version")? as String 530 | self.append(pkg.update_version(version)) 531 | end 532 | }) 533 | }) 534 | end 535 | end 536 | end 537 | 538 | be append(package: Package) => 539 | _latest.push(package) 540 | if _latest.size() == Packages().size() then 541 | _timers.cancel(_timer) 542 | end 543 | 544 | be complete() => 545 | Sort[Array[Package], Package](_local) 546 | _local.reverse_in_place() 547 | 548 | for pkg in _local.values() do 549 | _notify.write( 550 | pkg.string() + if pkg.selected then " *" else "" end, 551 | if pkg.selected then ANSI.bright_green() else "" end) 552 | 553 | if not pkg.selected then 554 | _notify.write("\n") 555 | continue 556 | end 557 | 558 | let pred = {(a: Package, b: Package): Bool => a == b } 559 | for latest in _latest.values() do 560 | if _local.contains(latest, pred) then continue end 561 | (let a, let b) = (pkg.update_version("?"), latest.update_version("?")) 562 | if (a == b) and (pkg.version != latest.version) then 563 | _notify .> write(" -- ") .> write(latest.string(), ANSI.yellow()) 564 | end 565 | end 566 | _notify.write("\n") 567 | end 568 | 569 | interface tag PonyupNotify 570 | be log(level: LogLevel, msg: String) 571 | be write(str: String, ansi_color_code: String = "") 572 | -------------------------------------------------------------------------------- /cmd/version.pony.in: -------------------------------------------------------------------------------- 1 | primitive Version 2 | fun apply() : String => 3 | "%%VERSION%%" 4 | -------------------------------------------------------------------------------- /corral.json: -------------------------------------------------------------------------------- 1 | { 2 | "deps": [ 3 | { 4 | "locator": "github.com/ponylang/crypto.git", 5 | "version": "1.2.3" 6 | }, 7 | { 8 | "locator": "github.com/ponylang/appdirs.git", 9 | "version": "0.1.5" 10 | }, 11 | { 12 | "locator": "github.com/ponylang/http.git", 13 | "version": "0.6.2" 14 | }, 15 | { 16 | "locator": "github.com/ponylang/json.git", 17 | "version": "0.1.0" 18 | } 19 | ], 20 | "info": { 21 | "version": "0.8.6" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /make.ps1: -------------------------------------------------------------------------------- 1 | Param( 2 | [Parameter(Position=0, HelpMessage="The action to take (fetch, build, test, buildtest, install, package, clean).")] 3 | [string] 4 | $Command = 'build', 5 | 6 | [Parameter(HelpMessage="The build configuration (Release, Debug).")] 7 | [string] 8 | $Config = "Release", 9 | 10 | [Parameter(HelpMessage="The version number to set.")] 11 | [string] 12 | $Version = "", 13 | 14 | [Parameter(HelpMessage="Architecture (native, x64).")] 15 | [string] 16 | $Arch = "x86-64", 17 | 18 | [Parameter(HelpMessage="Directory to install to.")] 19 | [string] 20 | $Destdir = "build/install" 21 | ) 22 | 23 | $ErrorActionPreference = "Stop" 24 | 25 | $target = "ponyup" # The name of the target executable. 26 | $targetPath = "cmd" # The source package directory. 27 | $testPath = "../test" # The path of the tests package relative to $targetPath. 28 | $isLibrary = $false 29 | 30 | $rootDir = Split-Path $script:MyInvocation.MyCommand.Path 31 | $srcDir = Join-Path -Path $rootDir -ChildPath $targetPath 32 | 33 | if ($Config -ieq "Release") 34 | { 35 | $configFlag = "" 36 | $buildDir = Join-Path -Path $rootDir -ChildPath "build/release" 37 | } 38 | elseif ($Config -ieq "Debug") 39 | { 40 | $configFlag = "--debug" 41 | $buildDir = Join-Path -Path $rootDir -ChildPath "build/debug" 42 | } 43 | else 44 | { 45 | throw "Invalid -Config path '$Config'; must be one of (Debug, Release)." 46 | } 47 | 48 | switch ($Version) 49 | { 50 | "release" { $Version = Get-Content "$rootDir\VERSION" } 51 | "nightly" { $Version = "nightly" + (Get-Date).ToString("yyyyMMdd") } 52 | default { $Version = (Get-Content "$rootDir\VERSION") + "-" + (& git rev-parse --short --verify HEAD) } 53 | } 54 | 55 | $ponyArgs = "--define openssl_0.9.0" 56 | 57 | Write-Host "Configuration: $Config" 58 | Write-Host "Version: $Version" 59 | Write-Host "Root directory: $rootDir" 60 | Write-Host "Source directory: $srcDir" 61 | Write-Host "Build directory: $buildDir" 62 | 63 | # generate pony templated files if necessary 64 | if (($Command -ne "clean") -and (Test-Path -Path "$rootDir\VERSION")) 65 | { 66 | $versionTimestamp = (Get-ChildItem -Path "$rootDir\VERSION").LastWriteTimeUtc 67 | Get-ChildItem -Path $srcDir -Include "*.pony.in" -Recurse | ForEach-Object { 68 | $templateFile = $_.FullName 69 | $ponyFile = $templateFile.Substring(0, $templateFile.Length - 3) 70 | $ponyFileTimestamp = [DateTime]::MinValue 71 | if (Test-Path $ponyFile) 72 | { 73 | $ponyFileTimestamp = (Get-ChildItem -Path $ponyFile).LastWriteTimeUtc 74 | } 75 | if (($ponyFileTimestamp -lt $versionTimestamp) -or ($ponyFileTimestamp -lt $_.LastWriteTimeUtc)) 76 | { 77 | Write-Host "$templateFile -> $ponyFile" 78 | ((Get-Content -Path $templateFile) -replace '%%VERSION%%', $Version) | Set-Content -Path $ponyFile 79 | } 80 | } 81 | } 82 | 83 | function BuildTarget 84 | { 85 | $binaryFile = Join-Path -Path $buildDir -ChildPath "$target.exe" 86 | $binaryTimestamp = [DateTime]::MinValue 87 | if (Test-Path $binaryFile) 88 | { 89 | $binaryTimestamp = (Get-ChildItem -Path $binaryFile).LastWriteTimeUtc 90 | } 91 | 92 | :buildFiles foreach ($file in (Get-ChildItem -Path "$srcDir\.." -Include "*.pony" -Recurse)) 93 | { 94 | if ($binaryTimestamp -lt $file.LastWriteTimeUtc) 95 | { 96 | Write-Host "corral run -- ponyc $configFlag $ponyArgs --cpu `"$Arch`" --output `"$buildDir`" --bin-name `"$target`" `"$srcDir`"" 97 | $output = (corral run -- ponyc $configFlag $ponyArgs --cpu "$Arch" --output "$buildDir" --bin-name "$target" "$srcDir") 98 | $output | ForEach-Object { Write-Host $_ } 99 | if ($LastExitCode -ne 0) { throw "Error" } 100 | break buildFiles 101 | } 102 | } 103 | } 104 | 105 | function BuildTest 106 | { 107 | $testTarget = "test.exe" 108 | 109 | $testFile = Join-Path -Path $buildDir -ChildPath $testTarget 110 | $testTimestamp = [DateTime]::MinValue 111 | if (Test-Path $testFile) 112 | { 113 | $testTimestamp = (Get-ChildItem -Path $testFile).LastWriteTimeUtc 114 | } 115 | 116 | :testFiles foreach ($file in (Get-ChildItem -Path "$srcDir\.." -Include "*.pony" -Recurse)) 117 | { 118 | if ($testTimestamp -lt $file.LastWriteTimeUtc) 119 | { 120 | $testDir = Join-Path -Path $srcDir -ChildPath $testPath 121 | Write-Host "corral run -- ponyc $configFlag $ponyArgs --cpu `"$Arch`" --output `"$buildDir`" --bin-name `"test`" `"$testDir`"" 122 | $output = (corral run -- ponyc $configFlag $ponyArgs --cpu "$Arch" --output "$buildDir" --bin-name test "$testDir") 123 | $output | ForEach-Object { Write-Host $_ } 124 | if ($LastExitCode -ne 0) { throw "Error" } 125 | break testFiles 126 | } 127 | } 128 | 129 | Write-Output "$testTarget is built" # force function to return a list of outputs 130 | return $testFile 131 | } 132 | 133 | switch ($Command.ToLower()) 134 | { 135 | "fetch" 136 | { 137 | Write-Host "corral fetch" 138 | $output = (corral fetch) 139 | $output | ForEach-Object { Write-Host $_ } 140 | if ($LastExitCode -ne 0) { throw "Error" } 141 | break 142 | } 143 | 144 | "build" 145 | { 146 | if (-not $isLibrary) 147 | { 148 | BuildTarget 149 | } 150 | else 151 | { 152 | Write-Host "$target is a library; nothing to build." 153 | } 154 | break 155 | } 156 | 157 | "buildtest" 158 | { 159 | BuildTest 160 | break 161 | } 162 | 163 | "test" 164 | { 165 | if ([Environment]::Is64BitOperatingSystem) { 166 | $env:PONYUP_PLATFORM = 'x86_64-pc-windows-msvc' 167 | } 168 | else { 169 | $env:PONYUP_PLATFORM = 'x86-pc-windows-msvc' 170 | } 171 | 172 | $testFile = (BuildTest)[-1] 173 | Write-Host "$testFile --sequential" 174 | & "$testFile" --sequential 175 | if ($LastExitCode -ne 0) { throw "Error" } 176 | break 177 | } 178 | 179 | "clean" 180 | { 181 | if (Test-Path "$buildDir") 182 | { 183 | Write-Host "Remove-Item -Path `"$buildDir`" -Recurse -Force" 184 | Remove-Item -Path "$buildDir" -Recurse -Force 185 | } 186 | break 187 | } 188 | 189 | "install" 190 | { 191 | if (-not $isLibrary) 192 | { 193 | $binDir = Join-Path -Path $Destdir -ChildPath "bin" 194 | 195 | if (-not (Test-Path $binDir)) 196 | { 197 | mkdir "$binDir" 198 | } 199 | 200 | $binFile = Join-Path -Path $buildDir -ChildPath "$target.exe" 201 | Copy-Item -Path $binFile -Destination $binDir -Force 202 | } 203 | else 204 | { 205 | Write-Host "$target is a library; nothing to install." 206 | } 207 | break 208 | } 209 | 210 | "package" 211 | { 212 | if (-not $isLibrary) 213 | { 214 | $binDir = Join-Path -Path $Destdir -ChildPath "bin" 215 | $package = "$target-x86-64-pc-windows-msvc.zip" 216 | Write-Host "Creating $package..." 217 | 218 | Compress-Archive -Path $binDir -DestinationPath "$buildDir\..\$package" -Force 219 | } 220 | else 221 | { 222 | Write-Host "$target is a library; nothing to package." 223 | } 224 | break 225 | } 226 | 227 | default 228 | { 229 | throw "Unknown command '$Command'; must be one of (fetch, build, test, buildtest, install, package, clean)." 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /ponyup-init.ps1: -------------------------------------------------------------------------------- 1 | Param([string] $Prefix = "$env:LOCALAPPDATA\ponyup", [bool] $SetPath = $true) 2 | $ErrorActionPreference = 'Stop' 3 | 4 | $tempParent = [System.IO.Path]::GetTempPath() 5 | $tempName = [System.Guid]::NewGuid() 6 | $tempPath = (Join-Path $tempParent $tempName) 7 | New-Item -ItemType Directory -Path $tempPath 8 | 9 | $downloadUrl = 'https://dl.cloudsmith.io/public/ponylang/releases/raw/versions/latest' 10 | 11 | $zipName = 'ponyup-x86-64-pc-windows-msvc.zip' 12 | $zipUrl = "$downloadUrl/$zipName" 13 | $zipPath = "$tempPath\$zipName" 14 | 15 | Write-Host "Downloading $zipUrl..." 16 | Invoke-WebRequest -Uri $zipUrl -Outfile $zipPath 17 | 18 | $ponyupPath = $Prefix 19 | if (-not (Test-Path $ponyupPath)) { 20 | New-Item -ItemType Directory -Path $ponyupPath 21 | } 22 | 23 | Write-Host "Unzipping to $ponyupPath..." 24 | Expand-Archive -Force -Path $zipPath -DestinationPath $ponyupPath 25 | 26 | $platform = 'x86_64-pc-windows-msvc' 27 | Write-Host "Setting platform to $platform..." 28 | Set-Content -Path "$ponyupPath\.platform" -Value $platform 29 | 30 | $version = & "$ponyupPath\bin\ponyup" version 31 | if ($version -match 'ponyup (\d+\.\d+\.\d+)') { 32 | $lockStr = "ponyup-release-$($Matches[1])-x86_64-windows" 33 | Write-Host "Locking ponyup version to $lockStr..." 34 | $lockPath = "$ponyupPath\.lock" 35 | 36 | $newContent = @() 37 | if (Test-Path $lockPath) { 38 | $content = Get-Content -Path $lockPath 39 | $content | Foreach-Object { 40 | if ($_ -match '^ponyup') { 41 | $newContent += $lockStr 42 | } 43 | else { 44 | $newContent += $_ 45 | } 46 | } 47 | } else { 48 | $newContent = @($lockStr) 49 | } 50 | 51 | Set-Content -Path "$ponyupPath\.lock" -Value $newContent 52 | } 53 | 54 | if ($SetPath) { 55 | $binDir = "$ponyupPath\bin" 56 | if (-not ($env:PATH -like "*$binDir*")) { 57 | Write-Host "Adding $binDir to PATH; you will need to restart your terminal to use it." 58 | $newPath = "$env:PATH;$binDir" 59 | [Environment]::SetEnvironmentVariable("PATH", $newPath, 'User') 60 | $env:PATH = $newPath 61 | } 62 | else { 63 | Write-Host "$binDir is already in PATH" 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /ponyup-init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -o errexit 4 | set -o nounset 5 | 6 | if [ -z "${XDG_DATA_HOME+x}" ]; then 7 | default_prefix="$HOME/.local/share" 8 | else 9 | default_prefix="$XDG_DATA_HOME" 10 | fi 11 | 12 | default_repository="releases" 13 | 14 | if [ "$(uname -s)" = "Darwin" ]; then 15 | # we have to use nightly releases on macOS 16 | # see https://github.com/ponylang/ponyup/issues/117 17 | default_repository="nightlies" 18 | fi 19 | 20 | exit_usage() { 21 | printf "%s\n\n" "ponyup-init.sh" 22 | echo "Options:" 23 | echo " --prefix Set ponyup install prefix. Default: ${default_prefix}" 24 | exit 1 25 | } 26 | 27 | json_field() { 28 | json=$1 29 | key=$2 30 | value_pattern=': *"\([^"]*\)"' 31 | echo "${json}" | sed "s/.*\"${key}\"${value_pattern}.*/\\1/" 32 | } 33 | 34 | DEFAULT="\033[39m" 35 | BLUE="\033[34m" 36 | RED="\033[31m" 37 | YELLOW="\033[33m" 38 | 39 | prefix="${default_prefix}" 40 | repository="${default_repository}" 41 | for arg in "$@"; do 42 | case "${arg}" in 43 | "--prefix="*) 44 | prefix=${arg##--prefix=} 45 | ;; 46 | "--repository="*) 47 | repository=${arg##--repository=} 48 | ;; 49 | *) 50 | exit_usage 51 | ;; 52 | esac 53 | done 54 | 55 | uname_m=$(uname -m) 56 | case "${uname_m}" in 57 | "x86_64" | "x86-64" | "x64" | "amd64") 58 | download_cpu="x86-64" 59 | platform_triple_cpu="x86_64" 60 | ;; 61 | "arm64" | "aarch64") 62 | download_cpu="arm64" 63 | platform_triple_cpu="arm64" 64 | ;; 65 | *) 66 | printf "%bUnsupported CPU type: ${uname_m}%b\n" "${RED}" "${DEFAULT}" 67 | exit 1 68 | ;; 69 | esac 70 | 71 | uname_s=$(uname -s) 72 | case "${uname_s}" in 73 | Darwin*) 74 | download_os="apple-darwin" 75 | platform_triple_os="apple-darwin" 76 | ;; 77 | Linux*) 78 | download_os="unknown-linux" 79 | platform_triple_os="unknown-linux" 80 | ;; 81 | *) 82 | printf "%bUnsupported OS: ${uname_s}%b\n" "${RED}" "${DEFAULT}" 83 | exit 1 84 | ;; 85 | esac 86 | 87 | platform_triple="${platform_triple_cpu}-${platform_triple_os}" 88 | 89 | platform_triple_distro="" 90 | case "${uname_s}" in 91 | Linux*) 92 | case $(cc -dumpmachine) in 93 | *gnu) 94 | case "$(lsb_release -d)" in 95 | *"Ubuntu 24.04"*) 96 | platform_triple_distro="ubuntu24.04" 97 | ;; 98 | *"Ubuntu 22.04"*) 99 | # we don't have these for arm64 so they it will fail to download 100 | platform_triple_distro="ubuntu22.04" 101 | ;; 102 | *"Linux Mint 21"*) 103 | # we don't have these for arm64 so they it will fail to download 104 | platform_triple_distro="ubuntu22.04" 105 | ;; 106 | *"Pop!_OS 24.04"*) 107 | platform_triple_distro="ubuntu24.04" 108 | ;; 109 | *"Pop!_OS 22.04"*) 110 | # we don't have these for arm64 so they it will fail to download 111 | platform_triple_distro="ubuntu22.04" 112 | ;; 113 | *) ;; 114 | esac 115 | ;; 116 | *x86_64-redhat-linux) 117 | case "$(lsb_release -d)" in 118 | *"Fedora Linux 41"*) 119 | platform_triple_distro="fedora41" 120 | ;; 121 | *) ;; 122 | esac 123 | ;; 124 | *musl) 125 | case "$(cat /etc/alpine-release)" in 126 | *3.21.*) 127 | platform_triple_distro="alpine3.21" 128 | ;; 129 | *3.20.*) 130 | # we don't have these for arm64 so they it will fail to download 131 | platform_triple_distro="alpine3.20" 132 | ;; 133 | *) 134 | # default to generic musl- we don't have these for arm64 so they it will 135 | # fail to download 136 | platform_triple_distro="musl" 137 | ;; 138 | esac 139 | ;; 140 | *) ;; 141 | esac 142 | ;; 143 | esac 144 | 145 | if [ "${platform_triple_distro}" != "" ]; then 146 | platform_triple="${platform_triple}-${platform_triple_distro}" 147 | fi 148 | 149 | if command -v sha256sum > /dev/null 2>&1; then 150 | sha256sum='sha256sum' 151 | elif command -v shasum > /dev/null 2>&1; then 152 | sha256sum='shasum --algorithm 256' 153 | else 154 | printf "%bNo checksum command found.%b\n" "${RED}" "${DEFAULT}" 155 | exit 1 156 | fi 157 | 158 | ponyup_root="${prefix}/ponyup" 159 | echo "ponyup_root = ${ponyup_root}" 160 | 161 | mkdir -p "${ponyup_root}/bin" 162 | echo "${platform_triple}" > "${ponyup_root}/.platform" 163 | 164 | query_url="https://api.cloudsmith.io/packages/ponylang/${repository}/" 165 | query="?query=ponyup-${download_cpu}-${download_os}&page=1&page_size=1" 166 | 167 | response=$(curl --request GET "${query_url}${query}") 168 | if [ "${response}" = "[]" ]; then 169 | printf "%bfailed to download ponyup%b\n" "${RED}" "${DEFAULT}" 170 | exit 1 171 | fi 172 | 173 | ponyup_pkg="$(json_field "${response}" version)" 174 | ponyup_pkg="${ponyup_pkg}-${platform_triple_cpu}-${download_os##*-}" 175 | 176 | if [ "${repository}" = releases ]; then 177 | ponyup_pkg="ponyup-release-${ponyup_pkg}" 178 | else 179 | ponyup_pkg="ponyup-nightly-${ponyup_pkg}" 180 | fi 181 | echo "${ponyup_pkg}" > "${ponyup_root}/.lock" 182 | 183 | checksum=$(json_field "${response}" checksum_sha256) 184 | dl_url=$(json_field "${response}" cdn_url) 185 | 186 | echo "checksum=${checksum}" 187 | echo "dl_url=${dl_url}" 188 | 189 | filename="$(basename "${dl_url}")" 190 | tmp_dir=/tmp/ponyup 191 | mkdir -p "${tmp_dir}" 192 | echo "downloading ${filename}" 193 | 194 | curl "${dl_url}" -o "${tmp_dir}/${filename}" 195 | 196 | dl_checksum="$(${sha256sum} "${tmp_dir}/${filename}" | awk '{ print $1 }')" 197 | 198 | if [ "${dl_checksum}" != "${checksum}" ]; then 199 | printf "%bchecksum mismatch:\n" "${RED}" 200 | printf " expected: %b${checksum}%b\n" "${BLUE}" "${RED}" 201 | printf " calculated: %b${dl_checksum}%b\n" "${YELLOW}" "${DEFAULT}" 202 | 203 | rm -f "${tmp_dir}/${filename}" 204 | exit 1 205 | fi 206 | echo "checksum ok" 207 | 208 | tar -xzf "${tmp_dir}/${filename}" -C "${tmp_dir}" 209 | mv "$(find ${tmp_dir} -name ponyup -type f)" "${ponyup_root}/bin/ponyup" 210 | 211 | printf "%bponyup placed in %b${ponyup_root}/bin%b\n" \ 212 | "${BLUE}" "${YELLOW}" "${DEFAULT}" 213 | 214 | if ! echo "$PATH" | grep -q "${ponyup_root}/bin"; then 215 | case "${SHELL}" in 216 | *fish) 217 | printf "%bYou should add %b${ponyup_root}/bin%b to \$PATH:%b\n" \ 218 | "${BLUE}" "${YELLOW}" "${BLUE}" "${DEFAULT}" 219 | printf "%bset -g fish_user_paths ${ponyup_root}/bin \$fish_user_paths%b\n" \ 220 | "${YELLOW}" "${DEFAULT}" 221 | ;; 222 | *) 223 | printf "%bYou should add %b${ponyup_root}/bin%b to \$PATH:%b\n" \ 224 | "${BLUE}" "${YELLOW}" "${BLUE}" "${DEFAULT}" 225 | printf "%bexport PATH=${ponyup_root}/bin:\$PATH%b\n" \ 226 | "${YELLOW}" "${DEFAULT}" 227 | ;; 228 | esac 229 | fi 230 | 231 | case "${uname_s}" in 232 | Linux*) 233 | if [ "${platform_triple_distro}" = "" ]; then 234 | printf "%bUnable to determine Linux platform type.%b\n" "${YELLOW}" "${DEFAULT}" 235 | printf "%bPlease see https://github.com/ponylang/ponyc/blob/main/INSTALL.md#linux to manually set your platform.%b\n" "${YELLOW}" "${DEFAULT}" 236 | 237 | # set prefix even if we don't know the default platform to set 238 | "${ponyup_root}/bin/ponyup" --prefix="${prefix}" 239 | 240 | # we don't consider this exit to be an error 241 | exit 0 242 | fi 243 | esac 244 | 245 | printf "%bsetting default platform to %b${platform_triple}%b\n" \ 246 | "${BLUE}" "${YELLOW}" "${DEFAULT}" 247 | 248 | "${ponyup_root}/bin/ponyup" --prefix="${prefix}" default "${platform_triple}" 249 | -------------------------------------------------------------------------------- /test/main.pony: -------------------------------------------------------------------------------- 1 | use "backpressure" 2 | use "files" 3 | use "json" 4 | use "net" 5 | use "pony_test" 6 | use "process" 7 | use "../cmd" 8 | 9 | actor Main is TestList 10 | new create(env: Env) => 11 | let test_dir = FilePath(FileAuth(env.root), "./.pony_test") 12 | if test_dir.exists() then test_dir.remove() end 13 | PonyTest(env, this) 14 | 15 | fun tag tests(test: PonyTest) => 16 | test(_TestParsePlatform) 17 | for package in Packages().values() do 18 | for channel in ["nightly"; "release"].values() do 19 | test(_TestSync(package, channel)) 20 | end 21 | end 22 | test(_TestSelect) 23 | 24 | class _TestParsePlatform is UnitTest 25 | fun name(): String => 26 | "parse platform" 27 | 28 | fun apply(h: TestHelper) ? => 29 | h.assert_no_error( 30 | {()? => Packages.from_string("?-?-?-" + _TestPonyup.platform(h))? }) 31 | 32 | let tests = 33 | [ as (String, ((CPU, OS, Distro) | None)): 34 | ("ponyc-?-?-x86_64-unknown-linux-ubuntu22.04", (AMD64, Linux, "ubuntu22.04")) 35 | ("ponyc-?-?-x64-linux-ubuntu22.04", (AMD64, Linux, "ubuntu22.04")) 36 | ("ponyc-x86_64-pc-linux-ubuntu24.04", (AMD64, Linux, "ubuntu24.04")) 37 | ("?-?-?-amd64-linux-ubuntu22.04", (AMD64, Linux, None)) 38 | ("ponyc-?-?-x86_64-alpine-linux-musl", (AMD64, Linux, "musl")) 39 | ("?-?-?-x86_64-alpine-linux-musl", (AMD64, Linux, None)) 40 | ("ponyc-?-?-x86_64-apple-darwin", (AMD64, Darwin, None)) 41 | ("?-?-?-darwin", (AMD64, Darwin, None)) 42 | ( "ponyc-?-?-musl" 43 | , (AMD64, Packages.platform_os()?, Packages.platform_distro("musl")) 44 | ) 45 | ("?-?-?-musl", (AMD64, Packages.platform_os()?, None)) 46 | ("ponyc-?-?-x86_64-linux", None) 47 | ("ponyc-?-?-x86_64-darwin", (AMD64, Darwin, None)) 48 | ("ponyc-?-?-x86_64-pc-windows-msvc", (AMD64, Windows, None)) 49 | ] 50 | for (input, expected) in tests.values() do 51 | h.log("input: " + input) 52 | match expected 53 | | (let cpu: CPU, let os: OS, let distro: Distro) => 54 | let pkg = Packages.from_string(input)? 55 | h.log(" => " + pkg.platform().string()) 56 | h.assert_eq[CPU](pkg.cpu, cpu) 57 | h.assert_eq[OS](pkg.os, os) 58 | match (pkg.distro, distro) 59 | | (let d: String, let d': String) => h.assert_eq[String](d, d') 60 | else h.assert_true((pkg.distro is None) and (distro is None)) 61 | end 62 | | None => h.assert_error({() ? => Packages.from_string(input)? }) 63 | end 64 | end 65 | 66 | class _TestSync is UnitTest 67 | let _pkg_name: String 68 | let _channel: String 69 | 70 | new iso create(pkg_name: String, channel: String) => 71 | _pkg_name = pkg_name 72 | _channel = channel 73 | 74 | fun name(): String => 75 | "sync - " + _pkg_name + "-" + _channel 76 | 77 | fun apply(h: TestHelper) => 78 | _SyncTester(h, h.env.root, _pkg_name, _channel) 79 | h.long_test(120_000_000_000) 80 | 81 | class _TestSelect is UnitTest 82 | let _ponyc_versions: Array[String] val = 83 | if Platform.osx() and Platform.arm() then 84 | ["release-0.55.0"; "release-0.55.1"] 85 | else 86 | ["release-0.58.0"; "release-0.58.1"] 87 | end 88 | 89 | fun name(): String => 90 | "select" 91 | 92 | fun apply(h: TestHelper) ? => 93 | let platform = _TestPonyup.platform(h) 94 | let install_args: {(String): Array[String] val} val = 95 | {(v) => ["update"; "ponyc"; v; "--platform=" + platform] } 96 | 97 | let link_path = 98 | ifdef windows then 99 | "./.pony_test/select/ponyup/bin/ponyc.bat" 100 | else 101 | "./.pony_test/select/ponyup/bin/ponyc" 102 | end 103 | let link = FilePath(FileAuth(h.env.root), link_path) 104 | 105 | let check = 106 | {()? => 107 | ifdef windows then 108 | var found = false 109 | with file = File.open(link) do 110 | for line in file.lines() do 111 | if line.contains(_ponyc_versions(1)?) then 112 | found = true 113 | break 114 | end 115 | end 116 | end 117 | h.assert_true(found, "batch file 0 did not contain the correct path") 118 | else 119 | h.assert_true(link.canonical()?.path.contains(_ponyc_versions(1)?)) 120 | end 121 | 122 | _TestPonyup.exec( 123 | h, "select", ["select"; "ponyc" ; _ponyc_versions(0)?], 124 | {()? => 125 | ifdef windows then 126 | with file = File.open(link) do 127 | for line in file.lines() do 128 | if line.contains(_ponyc_versions(0)?) then 129 | h.complete(true) 130 | return 131 | end 132 | end 133 | end 134 | h.fail("batch file did not contain the correct path") 135 | h.complete(false) 136 | else 137 | h.assert_true( 138 | link.canonical()?.path.contains(_ponyc_versions(0)?)) 139 | h.complete(true) 140 | end 141 | } val)? 142 | } val 143 | 144 | _TestPonyup.exec( 145 | h, "select", install_args(_ponyc_versions(0)?), 146 | {()(check) => 147 | try 148 | _TestPonyup.exec( 149 | h, "select", install_args(_ponyc_versions(1)?), 150 | {()? => check()? } val)? 151 | else 152 | h.complete(false) 153 | end 154 | } val)? 155 | 156 | h.long_test(120_000_000_000) 157 | 158 | actor _SyncTester is PonyupNotify 159 | let _h: TestHelper 160 | let _auth: AmbientAuth 161 | let _pkg_name: String 162 | embed _pkgs: Array[Package] = [] 163 | 164 | new create( 165 | h: TestHelper, 166 | auth: AmbientAuth, 167 | pkg_name: String, 168 | channel: String) 169 | => 170 | _h = h 171 | _auth = auth 172 | _pkg_name = pkg_name 173 | 174 | let platform = _TestPonyup.platform(h) 175 | let http_get = HTTPGet(NetAuth(_auth), this) 176 | try 177 | let pkg = Packages.from_fragments( 178 | _pkg_name, channel, "latest", platform.split("-"))? 179 | let query_string: String = 180 | Cloudsmith.repo_url(channel).clone() 181 | .> append(Cloudsmith.query(pkg)) 182 | .> replace("page_size=1", "page_size=2") 183 | log(Extra, "query url: " + query_string) 184 | http_get( 185 | query_string, 186 | {(_)(self = recover tag this end, pkg) => 187 | QueryHandler(self, {(res) => self.add_packages(pkg, consume res) }) 188 | }) 189 | end 190 | 191 | be add_packages(pkg: Package, res: Array[JsonObject val] iso) => 192 | for obj in (consume res).values() do 193 | try 194 | let file = obj.data("filename")? as String 195 | _pkgs.push(pkg.update_version(obj.data("version")? as String)) 196 | end 197 | end 198 | run() 199 | 200 | be run() => 201 | if _pkgs.size() == 0 then 202 | _h.complete(true) 203 | return 204 | end 205 | try 206 | let pkg = _pkgs.shift()? 207 | let name_with_channel = recover val pkg.name + "/" + pkg.channel end 208 | _h.env.out.print("sync -- " + name_with_channel) 209 | _TestPonyup.exec( 210 | _h, 211 | name_with_channel, 212 | [ "update"; pkg.name; pkg.channel + "-" + pkg.version 213 | "--platform=" + pkg.platform() 214 | ], 215 | {()(self = recover tag this end)? => 216 | _TestPonyup.check_files(_h, name_with_channel, pkg)? 217 | self.run() 218 | } val)? 219 | else 220 | _h.fail("exec error") 221 | _h.complete(false) 222 | end 223 | 224 | be log(level: LogLevel, msg: String) => 225 | match level 226 | | InternalErr | Err => 227 | _h.fail(msg) 228 | _h.env.err.print(msg) 229 | else 230 | _h.env.out.print(msg) 231 | end 232 | 233 | be write(str: String, ansi_color_code: String = "") => 234 | _h.env.out.write(str) 235 | 236 | primitive _TestPonyup 237 | fun platform(h: TestHelper): String => 238 | let env_key = "PONYUP_PLATFORM" 239 | for v in h.env.vars.values() do 240 | if not v.contains(env_key) then continue end 241 | return v.substring(env_key.size().isize() + 1) 242 | end 243 | h.log(env_key + " not set") 244 | h.fail() 245 | "?" 246 | 247 | fun ponyup_bin(auth: AmbientAuth): FilePath? => 248 | let bin_name = 249 | ifdef windows then 250 | "ponyup.exe" 251 | else 252 | "ponyup" 253 | end 254 | 255 | FilePath(FileAuth(auth), "./build") 256 | .join(if Platform.debug() then "debug" else "release" end)? 257 | .join(bin_name)? 258 | 259 | fun exec(h: TestHelper, dir: String, args: Array[String] val, cb: {()?} val) 260 | ? 261 | => 262 | let auth = h.env.root 263 | let bin = ponyup_bin(auth)? 264 | 265 | h.env.out.print(recover val 266 | let dbg_str = String 267 | .>append(bin.path) 268 | .>append(" --prefix=./.pony_test/") 269 | .>append(dir) 270 | .>append(" --verbose") 271 | for arg in args.values() do 272 | dbg_str.append(" ") 273 | dbg_str.append(arg) 274 | end 275 | dbg_str 276 | end) 277 | 278 | let ponyup_monitor = ProcessMonitor( 279 | StartProcessAuth(auth), 280 | ApplyReleaseBackpressureAuth(auth), 281 | object iso is ProcessNotify 282 | fun stdout(process: ProcessMonitor ref, data: Array[U8] iso) => 283 | h.log(String.from_array(consume data)) 284 | 285 | fun stderr(process: ProcessMonitor ref, data: Array[U8] iso) => 286 | h.log(String.from_array(consume data)) 287 | 288 | fun failed(p: ProcessMonitor, err: ProcessError) => 289 | h.fail("ponyup error: " + err.string()) 290 | h.complete(false) 291 | 292 | fun dispose(p: ProcessMonitor, exit: ProcessExitStatus) => 293 | if not (exit == Exited(0)) then 294 | h.fail("ponyup failed with status " + exit.string()) 295 | h.complete(false) 296 | else 297 | try 298 | cb()? 299 | else 300 | h.fail("exec callback threw an error") 301 | h.complete(false) 302 | end 303 | end 304 | end, 305 | bin, 306 | recover 307 | [bin.path; "--prefix=./.pony_test/" + dir; "--verbose"] .> append(args) 308 | end, 309 | h.env.vars) 310 | 311 | ponyup_monitor.done_writing() 312 | 313 | fun check_files(h: TestHelper, dir: String, pkg: Package) ? => 314 | let auth = h.env.root 315 | let install_path = FilePath(FileAuth(auth), "./.pony_test").join(dir)?.join("ponyup")? 316 | let bin_path = install_path.join(pkg.string())?.join("bin")? 317 | .join(pkg.name + ifdef windows then ".exe" else "" end)? 318 | h.assert_true(bin_path.exists()) 319 | --------------------------------------------------------------------------------