Repository navigation
Release #5
Workflow file for this run
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: Release | |
| # The reference pipeline from docs/release-flow.md, dogfooded with local | |
| # action paths: a tag releases itself with the actions it carries. | |
| on: | |
| push: | |
| branches: ["release/v**"] | |
| tags: ["v*"] | |
| workflow_dispatch: # cut-release dispatches the first run explicitly | |
| permissions: | |
| contents: write | |
| jobs: | |
| gate: | |
| name: release readiness gate | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.expect.outputs.version }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Derive the expected version from the ref | |
| id: expect | |
| run: | | |
| set -euo pipefail | |
| # Only human-pushed final tags reach the pipeline; workflow-token | |
| # marker pushes trigger nothing. | |
| case "${GITHUB_REF_TYPE}:${GITHUB_REF_NAME}" in | |
| branch:release/v*) version="${GITHUB_REF_NAME#release/v}" ;; | |
| tag:v*) version="${GITHUB_REF_NAME#v}" ;; | |
| *) version="" ;; | |
| esac | |
| echo "version=${version}" >> "$GITHUB_OUTPUT" | |
| - name: Require a verified signed tag (final path only) | |
| if: github.ref_type == 'tag' | |
| uses: ./.github/actions/require-signed-tag | |
| # No crate here: the declared version is the changelog's newest released | |
| # section, checked against the ref-derived one. | |
| - uses: ./.github/actions/check-release-readiness | |
| with: | |
| expected-version: ${{ steps.expect.outputs.version }} | |
| # The seal is four API calls and no build, so it belongs here: a tag that | |
| # does not carry the reviewed content fails in seconds, not after the | |
| # artifact jobs. | |
| - name: The tag must seal the newest candidate marker (early gate) | |
| if: github.ref_type == 'tag' | |
| uses: ./.github/actions/publish-draft-release | |
| with: | |
| version: ${{ steps.expect.outputs.version }} | |
| seal-only: "true" | |
| draft: | |
| name: build the draft pre-release (candidate path) | |
| needs: gate | |
| # Only release branches build candidates: a workflow_dispatch from any other | |
| # branch derives no version and must not create a draft. | |
| if: github.ref_type == 'branch' && startsWith(github.ref_name, 'release/v') | |
| runs-on: ubuntu-latest | |
| env: | |
| VERSION: ${{ needs.gate.outputs.version }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| # Notes render, draft create/refresh, marker push — one step. | |
| - uses: ./.github/actions/draft-release | |
| id: draft | |
| with: | |
| version: ${{ env.VERSION }} | |
| - uses: ./.github/actions/release-guidance | |
| with: | |
| version: ${{ env.VERSION }} | |
| marker-tag: ${{ steps.draft.outputs.marker }} | |
| commit: ${{ github.sha }} | |
| draft-url: ${{ steps.draft.outputs.url }} | |
| # The tags-signed ruleset resolves this to manual — the release manager | |
| # signs — and every candidate run dogfoods the detection. | |
| - uses: ./.github/actions/promote-release | |
| with: | |
| version: ${{ env.VERSION }} | |
| marker-tag: ${{ steps.draft.outputs.marker }} | |
| moving-major: "true" | |
| publish: | |
| name: publish the release (final path) | |
| needs: gate | |
| # Any tag reaching the pipeline is a human-pushed final tag: marker tags are | |
| # pushed with the workflow token and trigger nothing, and require-signed-tag | |
| # rejects unsigned tags. | |
| if: github.ref_type == 'tag' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| # Tree seal against the newest marker, the draft flip, and the moving | |
| # major — one step. | |
| - uses: ./.github/actions/publish-draft-release | |
| with: | |
| version: ${{ needs.gate.outputs.version }} | |
| moving-major: "true" |