fix(releases): carry PR read permission through release gates (#13)

## What

Grant the release gates the PR read permission their nested CI caller requires. Preserve optional PATCH checklist links. Closes #12.

## Why

GitHub rejected the first tag before any job ran because reusable-workflow permissions cannot increase at a lower level, even for skipped PR jobs. Keep v0.1.0 unchanged; publish the first 0.1 bundle as v0.1.1.

## Validation

Actionlint and zizmor pass. Dispatch the actual release workflow on this branch to check GitHub's complete call-chain validation without publishing (the top-level tag condition skips branch publication). Normal PR gates and reviewed version metadata remain required before tagging.

Commits are signed/DCO signed off. No new dependency or secret. Substantial AI assistance: Codex (GPT-6). Release-As: 0.1.1.


Release-As: 0.1.1
Signed-off-by: James Maes <james@kof22.com>
Co-Authored-By: Codex (GPT-6) <noreply@openai.com>
This commit was merged in pull request #13.
This commit is contained in:
james.maesandCodex authored and GitHub committed 2026-10-10 09:24:29 -05:00
1 parent ad09505900
commit e375cf3b07
4 files changed
+31 -5

No files matched your search

+17
View File
@@ -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 }}
+6 -3
View File
@@ -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:
+1 -1
View File
@@ -3,7 +3,7 @@
<!-- Generated by Release Please; permit its section spacing. -->
<!-- markdownlint-disable MD012 -->
## 0.1.0 (2026-10-10)
## 0.1.0 (2026-10-10) — unpublished
### Features
+7 -1
View File
@@ -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
@@ -116,6 +118,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