diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 638061a..1d3384a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -193,7 +193,6 @@ jobs: - smoke-unix - smoke-windows runs-on: ubuntu-latest - environment: production timeout-minutes: 10 permissions: contents: write @@ -241,3 +240,27 @@ jobs: fi gh release create "${release_args[@]}" + + publish: + name: Publish release + if: github.event_name == 'push' + needs: attest-and-draft + runs-on: ubuntu-latest + environment: production + timeout-minutes: 10 + permissions: + contents: write + steps: + - name: Publish the reviewed draft release + shell: bash + env: + GH_TOKEN: ${{ github.token }} + # No checkout in this job; tell gh which repository to target. + GH_REPO: ${{ github.repository }} + run: | + publish_args=("${RELEASE_TAG}" --draft=false) + # A prerelease (tag contains a hyphen) must not be marked latest. + if [[ "${RELEASE_TAG}" != *-* ]]; then + publish_args+=(--latest) + fi + gh release edit "${publish_args[@]}" diff --git a/docs/releasing.md b/docs/releasing.md index 860896a..c8b4e39 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -69,18 +69,22 @@ binary. A release build must report the tag version without the leading `v`. without publishing them. Included file timestamps are normalized to the tagged commit for reproducible archives. The workflow uploads the six archives and `checksums.txt` as one short-lived workflow artifact. Native Linux, macOS, and Windows jobs verify and run archives - from that exact artifact. Only after all native smoke tests pass does the final job attest the - archives and create the draft GitHub release. No maintainer PAT or repository secret is used. - To diagnose or revalidate an existing tag without creating a release, manually dispatch the same - workflow; manual runs stop after the native smoke tests: + from that exact artifact. Only after all native smoke tests pass does the attest-and-draft job + attest the archives and create the draft GitHub release. The workflow then pauses at the + `production` environment gate, awaiting maintainer approval before the publish job runs. No + maintainer PAT or repository secret is used. To diagnose or revalidate an existing tag without + creating a release, manually dispatch the same workflow; manual runs stop after the native smoke + tests: ```bash gh workflow run release.yml --field tag= ``` -5. Review the successful workflow, generated notes, checksums, attestations, and draft assets. -6. Publish the draft. With Release Immutability enabled, publishing - locks the tag and assets. +5. Review the drafted release on the Releases page — generated notes, checksums, attestations, and + the six archives. +6. Approve the pending `production` deployment on the release run. The publish job then flips the + draft to public (a prerelease tag is never marked latest). With Release Immutability enabled, + publishing locks the tag and assets. Do not move or reuse a released tag. Fixes require a new version.