diff --git a/.github/workflows/finalize-github-release.yaml b/.github/workflows/finalize-github-release.yaml new file mode 100644 index 0000000..753ebc2 --- /dev/null +++ b/.github/workflows/finalize-github-release.yaml @@ -0,0 +1,91 @@ +name: 🚀 Finalize GitHub Release +on: + workflow_dispatch: + inputs: + tag: + description: Published v-prefixed release tag whose Marketplace upload was accepted + required: true + type: string + source-run-id: + description: Tag release workflow run that accepted the Marketplace upload + required: true + type: string + acceptance-artifact-id: + description: Immutable Marketplace acceptance receipt artifact ID + required: true + type: string + signed-artifact-id: + description: Signed ZIP artifact ID from that run + required: true + type: string + notes-artifact-id: + description: Release notes artifact ID from that run + required: true + type: string +permissions: + actions: read + contents: write +concurrency: + group: release-refs/tags/${{ inputs.tag }} + cancel-in-progress: false +jobs: + finalize: + name: 🚀 Finalize GitHub Release + runs-on: ubuntu-26.04 + environment: release + steps: + - name: 🔍 Verify the original tag run + id: source + env: + GH_TOKEN: ${{ github.token }} + SOURCE_RUN: ${{ inputs.source-run-id }} + TAG: ${{ inputs.tag }} + run: | + set -euo pipefail + commit=$(gh api "repos/$GITHUB_REPOSITORY/actions/runs/$SOURCE_RUN" \ + --jq '. | select(.event == "push" and .path == ".github/workflows/release.yaml" and .head_branch == env.TAG) | .head_sha') + echo "commit=$commit" >>"$GITHUB_OUTPUT" + - name: 📩 Download Marketplace acceptance + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 + with: + artifact-ids: ${{ inputs.acceptance-artifact-id }} + run-id: ${{ inputs.source-run-id }} + github-token: ${{ github.token }} + path: ${{ runner.temp }}/acceptance + - name: 📩 Download signed plugin + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 + with: + artifact-ids: ${{ inputs.signed-artifact-id }} + run-id: ${{ inputs.source-run-id }} + github-token: ${{ github.token }} + path: dist + - name: 📩 Download release notes + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 + with: + artifact-ids: ${{ inputs.notes-artifact-id }} + run-id: ${{ inputs.source-run-id }} + github-token: ${{ github.token }} + path: ${{ runner.temp }}/notes + - name: 🔍 Check downloaded files against the acceptance receipt + env: + TAG: ${{ inputs.tag }} + COMMIT: ${{ steps.source.outputs.commit }} + RECEIPT: ${{ runner.temp }}/acceptance/marketplace-acceptance.json + run: | + set -euo pipefail + test "$(jq -r .tag "$RECEIPT")" = "$TAG" + test "$(jq -r .commit "$RECEIPT")" = "$COMMIT" + read -r digest _ < <(sha256sum dist/*-signed.zip) + test "$digest" = "$(jq -r .sha256 "$RECEIPT")" + read -r digest _ < <(sha256sum "$RUNNER_TEMP/notes/release-notes.md") + test "$digest" = "$(jq -r .notesSha256 "$RECEIPT")" + - name: 🚀 Publish GitHub release + uses: tox-dev/github-workflows/publish-github-release@2c1f5e4ceda37c41eb8367b5cbeaa741aa60a566 # 6.5.2 + env: + GH_TOKEN: ${{ github.token }} + with: + tag: ${{ inputs.tag }} + commit: ${{ steps.source.outputs.commit }} + title: ${{ inputs.tag }} + notes-file: ${{ runner.temp }}/notes/release-notes.md + assets-directory: dist diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index d493edf..d3b5994 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -143,7 +143,7 @@ jobs: if: always() && needs.release-notes.result == 'success' && needs.sign.result == 'success' && needs.marketplace-check.result == 'success' && (needs.marketplace-publish.result == 'success' || (needs.marketplace-publish.result == 'skipped' && needs.marketplace-check.outputs.publish == 'false')) runs-on: ubuntu-26.04 permissions: - contents: read + contents: write environment: release steps: - name: 📩 Download release notes