From cd843c6a3cc9980f0ef8b96e2795f2b714f06fba Mon Sep 17 00:00:00 2001 From: James Maes Date: Sat, 10 Oct 2026 09:21:17 -0500 Subject: [PATCH 1/2] fix(releases): carry PR read permission through release gates GitHub validates nested workflow permissions even when the PR gate is skipped. Preserve optional PATCH checklist links and keep the failed 0.1.0 tag reserved. Release-As: 0.1.1 Co-Authored-By: Codex (GPT-6) Signed-off-by: James Maes --- .github/workflows/release-standards.yml | 9 ++++++--- CHANGELOG.md | 2 +- docs/releases.md | 4 ++++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release-standards.yml b/.github/workflows/release-standards.yml index 8f4870f..8ab3362 100644 --- a/.github/workflows/release-standards.yml +++ b/.github/workflows/release-standards.yml @@ -51,11 +51,13 @@ jobs: } echo "pr=$pr" >> "$GITHUB_OUTPUT" # Preflight is approved before tagging; shipping checks follow publication. - checklist='' + annotation="$(git for-each-ref --format='%(contents)' "refs/tags/$TAG")" + checklist="$(printf '%s\n' "$annotation" | sed -n 's/^Release checklist: //p' | head -n 1)" if [[ "$version" == *.0 ]]; then - annotation="$(git for-each-ref --format='%(contents)' "refs/tags/$TAG")" + [[ -n "$checklist" ]] + fi + if [[ -n "$checklist" ]]; then prefix="https://github.com/$GH_REPO/issues/" - checklist="$(printf '%s\n' "$annotation" | grep -F 'Release checklist: ' | head -n 1 | sed 's/^Release checklist: //')" [[ "$checklist" == "$prefix"* ]] issue="${checklist#"$prefix"}" [[ "$issue" =~ ^[1-9][0-9]*$ ]] @@ -70,6 +72,7 @@ jobs: uses: ./.github/workflows/ci.yml permissions: contents: read + pull-requests: read # required by ci.yml's nested PR caller even on tag events security-events: write build: diff --git a/CHANGELOG.md b/CHANGELOG.md index 912fc3a..ebd26f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ -## 0.1.0 (2026-10-10) +## 0.1.0 (2026-10-10) — unpublished ### Features diff --git a/docs/releases.md b/docs/releases.md index 1c5a158..1d363de 100644 --- a/docs/releases.md +++ b/docs/releases.md @@ -116,6 +116,10 @@ same Git/archive tool versions. The builder refuses an existing output directory ## Failed releases +The initial `v0.1.0` tag was reserved by a workflow-startup failure; no bundle was +published for it. The first published bundle is `v0.1.1`. Keep the original tag +unchanged; use a new version when a tagged workflow needs a source fix. + Never replace published assets or move/reuse a version tag. Fix a published error with a new release. A failed upload or publication leaves a draft; inspect its run and assets, then remove **only the unpublished draft** before rerunning the tag's -- 2.54.0 From dd413895336b3984f6c29eba72a860e2cbce9030 Mon Sep 17 00:00:00 2001 From: James Maes Date: Sat, 10 Oct 2026 09:22:33 -0500 Subject: [PATCH 2/2] fix(releases): wait for publication before proposing another version Co-Authored-By: Codex (GPT-6) Signed-off-by: James Maes --- .github/workflows/ci.yml | 17 +++++++++++++++++ docs/releases.md | 4 +++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e10d50f..9fd418a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -125,7 +125,24 @@ jobs: permission-contents: write permission-pull-requests: write + # Version files merge before publication; wait for the publisher's label. + - name: Check for unpublished merged releases + id: pending + env: + GH_TOKEN: ${{ steps.app.outputs.token }} + GH_REPO: ${{ github.repository }} + run: | + set -euo pipefail + pending="$(gh api --paginate "repos/$GH_REPO/pulls?state=closed&per_page=100" --jq '.[] | select(.merged_at != null and any(.labels[]; .name == "autorelease: pending")) | .number')" + if [[ -n "$pending" ]]; then + echo 'can-propose=false' >> "$GITHUB_OUTPUT" + echo "Waiting for publication of merged release PR(s): $pending" + else + echo 'can-propose=true' >> "$GITHUB_OUTPUT" + fi + - name: Propose a semantic release + if: steps.pending.outputs.can-propose == 'true' uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5.0.0 with: token: ${{ steps.app.outputs.token }} diff --git a/docs/releases.md b/docs/releases.md index 1d363de..db9aacf 100644 --- a/docs/releases.md +++ b/docs/releases.md @@ -80,7 +80,9 @@ and Release Please actions are pinned and tracked by Dependabot. See the the checklist; reruns all repository CI gates; builds and attests the assets; and waits for the `release` environment approval. Publication creates a draft with all assets and notes, then publishes it. The release PR is marked - `autorelease: tagged` so the next version can be proposed. + `autorelease: tagged` so the next version can be proposed. Version proposals wait + while a merged release PR has `autorelease: pending`; a failed, permanently + retired version uses `autorelease: failed` instead. These bundles ship no compiled software, so the compiled-artifact SBOM requirement does not apply. The included workflows/configs retain their upstream pins; source -- 2.54.0