Finalize Releases #922
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Finalize Releases | |
| on: | |
| workflow_run: | |
| workflows: [CI] | |
| types: [completed] | |
| # A release PR merge starts CI and this workflow. Never cancel a finalizer after release-please has | |
| # created its tag: that ref is what starts the non-cancelable signed build. | |
| concurrency: | |
| group: finalize-releases-master | |
| cancel-in-progress: false | |
| permissions: | |
| contents: read | |
| jobs: | |
| finalize: | |
| name: Finalize merged release PRs | |
| if: >- | |
| github.event.workflow_run.conclusion == 'success' && | |
| github.event.workflow_run.event == 'push' && | |
| github.event.workflow_run.head_branch == 'master' | |
| runs-on: ${{ vars.CI_RUNNER_LINUX || 'ubuntu-latest' }} | |
| timeout-minutes: 10 | |
| steps: | |
| # workflow_run is privileged, so only check out the protected default branch. The next step | |
| # proves this script is byte-identical to the policy included in the CI-tested merge SHA. | |
| - name: Checkout release automation | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| ref: master | |
| persist-credentials: false | |
| sparse-checkout: .github/scripts | |
| - parallel: | |
| - name: Verify release automation was CI-tested | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | |
| env: | |
| TESTED_SHA: ${{ github.event.workflow_run.head_sha }} | |
| with: | |
| github-token: ${{ github.token }} | |
| script: | | |
| const path = '.github/scripts/release-automation.cjs' | |
| const read = async (ref) => { | |
| const response = await github.rest.repos.getContent({ | |
| ...context.repo, | |
| path, | |
| ref, | |
| }) | |
| return response.data.sha | |
| } | |
| const [testedBlob, currentBlob] = await Promise.all([ | |
| read(process.env.TESTED_SHA), | |
| read('master'), | |
| ]) | |
| if (currentBlob !== testedBlob) { | |
| throw new Error(`${path} changed after CI-tested release candidate ${process.env.TESTED_SHA}`) | |
| } | |
| - name: Mint release bot token | |
| id: release-token | |
| uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3 | |
| with: | |
| app-id: ${{ secrets.BOT_APP_ID }} | |
| private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }} | |
| permission-contents: write | |
| permission-issues: write | |
| permission-pull-requests: write | |
| # Bind release-please to the exact commit that this successful CI run tested. Normal master | |
| # pushes are no-ops, and release-please may only see this one pending Desktop release PR. | |
| - name: Resolve tested release candidate | |
| id: candidate | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | |
| env: | |
| TESTED_SHA: ${{ github.event.workflow_run.head_sha }} | |
| with: | |
| github-token: ${{ steps.release-token.outputs.token }} | |
| script: | | |
| const automation = require('./.github/scripts/release-automation.cjs') | |
| await automation.resolveCandidate({ | |
| core, | |
| github, | |
| ...context.repo, | |
| testedSha: process.env.TESTED_SHA, | |
| }) | |
| # release-please reads these files from current master even when it releases an older, tested | |
| # release-PR merge SHA. Ordinary commits may advance master; release policy must not drift. | |
| - name: Verify tested release configuration is still current | |
| if: ${{ steps.candidate.outputs.state == 'pending' }} | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | |
| env: | |
| TESTED_SHA: ${{ steps.candidate.outputs.sha }} | |
| with: | |
| github-token: ${{ steps.release-token.outputs.token }} | |
| script: | | |
| const automation = require('./.github/scripts/release-automation.cjs') | |
| await automation.verifyConfig({ | |
| github, | |
| ...context.repo, | |
| testedSha: process.env.TESTED_SHA, | |
| }) | |
| # release-please recovers the version and notes from a merged release PR. Configured Releases | |
| # stay draft, so users never see a release before its signed artifacts have been verified. | |
| - name: Create draft releases | |
| id: release | |
| if: ${{ steps.candidate.outputs.state == 'pending' }} | |
| uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5.0.0 | |
| with: | |
| token: ${{ steps.release-token.outputs.token }} | |
| config-file: release-please-config.json | |
| manifest-file: .release-please-manifest.json | |
| target-branch: master | |
| skip-github-pull-request: true | |
| # force-tag-creation makes release-please create the lightweight ref with the App token before | |
| # it creates the draft. That tag push starts release-desktop.yml; validate that release-please | |
| # acted on exactly the commit this CI run tested. | |
| - name: Verify started Desktop release | |
| if: ${{ steps.candidate.outputs.state == 'pending' }} | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | |
| env: | |
| RELEASE_CREATED: ${{ steps.release.outputs.release_created }} | |
| RELEASE_SHA: ${{ steps.candidate.outputs.sha }} | |
| RELEASE_TAG: ${{ steps.candidate.outputs.tag }} | |
| RELEASE_PLEASE_SHA: ${{ steps.release.outputs.sha }} | |
| RELEASE_PLEASE_TAG: ${{ steps.release.outputs.tag_name }} | |
| with: | |
| github-token: ${{ steps.release-token.outputs.token }} | |
| script: | | |
| const automation = require('./.github/scripts/release-automation.cjs') | |
| await automation.verifyStartedRelease({ | |
| core, | |
| github, | |
| ...context.repo, | |
| releaseCreated: process.env.RELEASE_CREATED, | |
| releasePleaseSha: process.env.RELEASE_PLEASE_SHA, | |
| releasePleaseTag: process.env.RELEASE_PLEASE_TAG, | |
| releaseSha: process.env.RELEASE_SHA, | |
| releaseTag: process.env.RELEASE_TAG, | |
| }) |