diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 064dc37..ed6d911 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -1,12 +1,11 @@ name: Build artifacts on: - pull_request: - push: workflow_dispatch: + workflow_call: jobs: - build-artifacts-macOS: + build-artifacts-X64-macOS: runs-on: macos-12 steps: - uses: actions/checkout@v3 @@ -20,29 +19,11 @@ jobs: uses: actions/upload-artifact@v3.1.2 with: # Artifact name - name: nix-actions-cache-macOS + name: nix-actions-cache-X64-macOS path: result/bin/nix-actions-cache retention-days: 1 - check-artifacts-macOS: - runs-on: macos-12 - needs: build-artifacts-macOS - steps: - - uses: actions/checkout@v3 - - uses: actions/download-artifact@v3 - with: - name: nix-actions-cache-macOS - path: cache-binary - - name: Make the binary executable - run: chmod +x ./cache-binary/nix-actions-cache - - uses: DeterminateSystems/nix-installer-action-cache@main - with: - cache-binary: ./cache-binary/nix-actions-cache - - - name: "Build something" - run: "nix build .# -L" - - build-artifacts-Linux: + build-artifacts-X64-Linux: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 @@ -56,24 +37,6 @@ jobs: uses: actions/upload-artifact@v3.1.2 with: # Artifact name - name: nix-actions-cache-Linux + name: nix-actions-cache-X64-Linux path: result/bin/nix-actions-cache retention-days: 1 - - check-artifacts-Linux: - runs-on: ubuntu-22.04 - needs: build-artifacts-Linux - steps: - - uses: actions/checkout@v3 - - uses: actions/download-artifact@v3 - with: - name: nix-actions-cache-Linux - path: cache-binary - - name: Make the binary executable - run: chmod +x ./cache-binary/nix-actions-cache - - uses: DeterminateSystems/nix-installer-action-cache@main - with: - cache-binary: ./cache-binary/nix-actions-cache - - - name: "Build something" - run: "nix build .# -L" diff --git a/.github/workflows/release-branches.yml b/.github/workflows/release-branches.yml new file mode 100644 index 0000000..c27540b --- /dev/null +++ b/.github/workflows/release-branches.yml @@ -0,0 +1,52 @@ +name: Release Branch + +on: + push: + branches: + # NOTE: make sure any branches here are also valid directory names, + # otherwise creating the directory and uploading to s3 will fail + - "main" + +jobs: + build: + uses: ./.github/workflows/build.yaml + + release: + needs: build + + concurrency: release + runs-on: ubuntu-latest + permissions: + contents: read + 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-X64-macOS + path: cache-binary-X64-macOS + - name: Persist the cache binary + run: cp ./cache-binary-macOS/nix-actions-cache ./artifacts/nix-actions-cache-X64-macOS + + - uses: actions/download-artifact@v3 + with: + name: nix-actions-cache-X64-Linux + path: cache-binary-X64-Linux + - name: Persist the cache binary + run: cp ./cache-binary-Linux/nix-actions-cache ./artifacts/nix-actions-cache-X64-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..f17205d --- /dev/null +++ b/.github/workflows/release-prs.yml @@ -0,0 +1,61 @@ +name: Release PR + +on: + pull_request: + types: + - opened + - reopened + - synchronize + - labeled + +jobs: + build: + uses: ./.github/workflows/build.yaml + + release: + needs: build + + concurrency: release + # Only intra-repo PRs are allowed to have PR artifacts uploaded + # We only want to trigger once the upload once in the case the upload label is added, not when any label is added + if: | + github.event.pull_request.head.repo.full_name == 'DeterminateSystems/nix-actions-cache' + && ( + (github.event.action == 'labeled' && github.event.label.name == 'upload to s3') + || (github.event.action != 'labeled' && 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 + contents: read + 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-X64-macOS + path: cache-binary-X64-macOS + - name: Persist the cache binary + run: cp ./cache-binary-X64-macOS/nix-actions-cache ./artifacts/nix-actions-cache-X64-macOS + + - uses: actions/download-artifact@v3 + with: + name: nix-actions-cache-X64-Linux + path: cache-binary-X64-Linux + - name: Persist the cache binary + run: cp ./cache-binary-X64-Linux/nix-actions-cache ./artifacts/nix-actions-cache-X64-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..a9dbd24 --- /dev/null +++ b/.github/workflows/release-tags.yml @@ -0,0 +1,58 @@ +name: Release Tags + +on: + push: + tags: + - "v*.*.*" + +jobs: + build: + uses: ./.github/workflows/build.yaml + + release: + needs: build + + 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-X64-macOS + path: cache-binary-X64-macOS + - name: Persist the cache binary + run: cp ./cache-binary-X64-macOS/nix-actions-cache ./artifacts/nix-actions-cache-X64-macOS + + - uses: actions/download-artifact@v3 + with: + name: nix-actions-cache-X64-Linux + path: cache-binary-X64-Linux + - name: Persist the cache binary + run: cp ./cache-binary-X64-Linux/nix-actions-cache ./artifacts/nix-actions-cache-X64-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..37358d0 --- /dev/null +++ b/.github/workflows/upload_s3.sh @@ -0,0 +1,96 @@ +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 + +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/rev/$GIT_ISH/X64-macOS +\`\`\` + +x86_64 Linux: + +\`\`\` +curl --output nix-actions-cache --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix-actions-cache/rev/$GIT_ISH/X64-Linux +\`\`\` + +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/${TYPE}/${TYPE_ID}/X64-macOS +\`\`\` + +x86_64 Linux: + +\`\`\` +curl --output nix-actions-cache --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix-actions-cache/${TYPE}/${TYPE_ID}/X64-Linux +\`\`\` +EOF