From e6c72f9c328b0aa9a64a048d25f45962d1731bb2 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Sun, 21 May 2023 20:27:24 -0400 Subject: [PATCH] Release via install.determinate.systems --- .github/workflows/release-branches.yml | 49 +++++++++++++ .github/workflows/release-prs.yml | 49 +++++++++++++ .github/workflows/release-tags.yml | 53 ++++++++++++++ .github/workflows/upload_s3.sh | 98 ++++++++++++++++++++++++++ 4 files changed, 249 insertions(+) create mode 100644 .github/workflows/release-branches.yml create mode 100644 .github/workflows/release-prs.yml create mode 100644 .github/workflows/release-tags.yml create mode 100755 .github/workflows/upload_s3.sh diff --git a/.github/workflows/release-branches.yml b/.github/workflows/release-branches.yml new file mode 100644 index 0000000..bb182f1 --- /dev/null +++ b/.github/workflows/release-branches.yml @@ -0,0 +1,49 @@ +name: Release Branch + +on: + workflow_run: + workflows: ["Build artifacts"] + branches: + # NOTE: make sure any branches here are also valid directory names, + # otherwise creating the directory and uploading to s3 will fail + - "main" + types: + - completed + +jobs: + release: + concurrency: release + runs-on: ubuntu-latest + permissions: + id-token: write # In order to request a JWT for AWS auth + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v2 + with: + role-to-assume: ${{ secrets.AWS_S3_UPLOAD_ROLE }} + aws-region: us-east-2 + + - name: Create the artifacts directory + run: rm -rf ./artifacts && mkdir ./artifacts + + - uses: actions/download-artifact@v3 + with: + name: nix-actions-cache-macOS + path: cache-binary-macOS + - name: Persist the cache binary + run: cp ./cache-binary-macOS/nix-actions-cache ./artifacts/nix-actions-cache-macOS + + - uses: actions/download-artifact@v3 + with: + name: nix-actions-cache-Linux + path: cache-binary-Linux + - name: Persist the cache binary + run: cp ./cache-binary-Linux/nix-actions-cache ./artifacts/nix-actions-cache-Linux + + - name: Publish Release (Branch) + env: + AWS_BUCKET: ${{ secrets.AWS_S3_UPLOAD_BUCKET }} + run: | + .github/workflows/upload_s3.sh branch "${{ github.ref_name }}" "$GITHUB_SHA" diff --git a/.github/workflows/release-prs.yml b/.github/workflows/release-prs.yml new file mode 100644 index 0000000..c8d3c5e --- /dev/null +++ b/.github/workflows/release-prs.yml @@ -0,0 +1,49 @@ +name: Release PR + +on: + pull_request: + types: + - opened + - reopened + - synchronize + - labeled + +jobs: + release: + concurrency: release + # Only intra-repo PRs are allowed to have PR artifacts uploaded + if: github.event.pull_request.head.repo.full_name == 'DeterminateSystems/nix-installer' && contains(github.event.pull_request.labels.*.name, 'upload to s3') + runs-on: ubuntu-latest + permissions: + id-token: write # In order to request a JWT for AWS auth + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Create the artifacts directory + run: rm -rf ./artifacts && mkdir ./artifacts + + - uses: actions/download-artifact@v3 + with: + name: nix-actions-cache-macOS + path: cache-binary-macOS + - name: Persist the cache binary + run: cp ./cache-binary-macOS/nix-actions-cache ./artifacts/nix-actions-cache-macOS + + - uses: actions/download-artifact@v3 + with: + name: nix-actions-cache-Linux + path: cache-binary-Linux + - name: Persist the cache binary + run: cp ./cache-binary-Linux/nix-actions-cache ./artifacts/nix-actions-cache-Linux + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v2 + with: + role-to-assume: ${{ secrets.AWS_S3_UPLOAD_ROLE }} + aws-region: us-east-2 + - name: Publish Release (PR) + env: + AWS_BUCKET: ${{ secrets.AWS_S3_UPLOAD_BUCKET }} + run: | + .github/workflows/upload_s3.sh pr "${{ github.event.pull_request.number }}" "${{ github.event.pull_request.head.sha }}" diff --git a/.github/workflows/release-tags.yml b/.github/workflows/release-tags.yml new file mode 100644 index 0000000..a8bfe43 --- /dev/null +++ b/.github/workflows/release-tags.yml @@ -0,0 +1,53 @@ +name: Release Tags + +on: + push: + tags: + - "v*.*.*" + +jobs: + release: + concurrency: release + runs-on: ubuntu-latest + permissions: + contents: write # In order to upload artifacts to GitHub releases + id-token: write # In order to request a JWT for AWS auth + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Create the artifacts directory + run: rm -rf ./artifacts && mkdir ./artifacts + + - uses: actions/download-artifact@v3 + with: + name: nix-actions-cache-macOS + path: cache-binary-macOS + - name: Persist the cache binary + run: cp ./cache-binary-macOS/nix-actions-cache ./artifacts/nix-actions-cache-macOS + + - uses: actions/download-artifact@v3 + with: + name: nix-actions-cache-Linux + path: cache-binary-Linux + - name: Persist the cache binary + run: cp ./cache-binary-Linux/nix-actions-cache ./artifacts/nix-actions-cache-Linux + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v2 + with: + role-to-assume: ${{ secrets.AWS_S3_UPLOAD_ROLE }} + aws-region: us-east-2 + - name: Publish Release to S3 (Tag) + env: + AWS_BUCKET: ${{ secrets.AWS_S3_UPLOAD_BUCKET }} + run: | + ./upload_s3.sh "tag" "$GITHUB_REF_NAME" "$GITHUB_SHA" + - name: Publish Release to GitHub (Tag) + uses: softprops/action-gh-release@v1 + with: + fail_on_unmatched_files: true + draft: true + files: | + artifacts/** + nix-installer.sh diff --git a/.github/workflows/upload_s3.sh b/.github/workflows/upload_s3.sh new file mode 100755 index 0000000..4647f32 --- /dev/null +++ b/.github/workflows/upload_s3.sh @@ -0,0 +1,98 @@ +set -eu + +TYPE="$1" +TYPE_ID="$2" +GIT_ISH="$3" + +if [ "$TYPE" == "tag" ]; then + DEST="${TYPE_ID}" +else + DEST="${TYPE}_${TYPE_ID}" +fi + +is_tag() { + if [[ "$GITHUB_REF_TYPE" == "tag" ]]; then + return 0 + else + return 1 + fi +} + +# If the revision directory has already been created in S3 somehow, we don't want to reupload +if aws s3 ls "$AWS_BUCKET"/"$GIT_ISH"/; then + # Only exit if it's not a tag (since we're tagging a commit previously pushed to main) + if ! is_tag; then + echo "Revision $GIT_ISH was already uploaded; exiting" + exit 1 + fi +fi + +sudo chown $USER: -R artifacts/ + +mkdir "$DEST" +mkdir "$GIT_ISH" + +for artifact in $(find artifacts/ -type f); do + chmod +x "$artifact" + cp "$artifact" "$DEST"/ + cp "$artifact" "$GIT_ISH"/ +done + +# If any artifact already exists in S3 and the hash is the same, we don't want to reupload +check_reupload() { + dest="$1" + + for file in $(find "$dest" -type f); do + artifact_path="$dest"/"$(basename "$artifact")" + md5="$(md5sum "$artifact" | cut -d' ' -f1)" + obj="$(aws s3api head-object --bucket "$AWS_BUCKET" --key "$artifact_path" || echo '{}')" + obj_md5="$(jq -r .ETag <<<"$obj" | jq -r)" # head-object call returns ETag quoted, so `jq -r` again to unquote it + + if [[ "$md5" == "$obj_md5" ]]; then + echo "Artifact $artifact was already uploaded; exiting" + # If we already uploaded to a tag, that's probably bad + is_tag && exit 1 || exit 0 + fi + done +} + +check_reupload "$DEST" +if ! is_tag; then + check_reupload "$GIT_ISH" +fi + +aws s3 sync "$DEST"/ s3://"$AWS_BUCKET"/"$DEST"/ --acl public-read +if ! is_tag; then + aws s3 sync "$GIT_ISH"/ s3://"$AWS_BUCKET"/"$GIT_ISH"/ --acl public-read +fi + + +cat <<-EOF >> $GITHUB_STEP_SUMMARY +This commit's nix-actions-cache binaries can be fetched from: + +Intel macOS: + +``` +curl --output nix-actions-cache --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix-actions-cache/macOS/rev/$GIT_ISH +``` + +x86_64 Linux: + +``` +curl --output nix-actions-cache --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix-actions-cache/Linux/rev/$GIT_ISH +``` + +Or generally from this ${TYPE}: + +Intel macOS: + +``` +curl --output nix-actions-cache --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix-actions-cache/macOS/${TYPE}/${DEST} +``` + +x86_64 Linux: + +``` +curl --output nix-actions-cache --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix-actions-cache/Linux/${TYPE}/${DEST} +``` +EOF