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/.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..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 @@ -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