From 13a86d6f25b7ba118d6bc4c9f45d5ce0cd7ff852 Mon Sep 17 00:00:00 2001 From: Bill Traynor Date: Tue, 13 Oct 2026 13:37:10 -0400 Subject: [PATCH] Keep the version stamp on the release tag when main refuses the push The riscv organization ruleset requires signed commits and a passing DCO check on the default branch. version-bot.yml pushes its antora.yml stamp straight to main before tagging, and a bot's direct push satisfies neither, so the push is refused in every riscv repository. The bot then reset to main and tagged the unstamped commit: the tag's antora.yml named v0.0, scripts/build-pages-site.sh skipped it, and the release's versioned site path disappeared on the next push to main. Seen on riscv/riscv-memory-tagging v0.51. On refusal, keep the stamp commit and tag it, pushing only the tag. The ruleset targets branches, so the tag lands and carries a descriptor naming its own version. build-pdf.yml's stamp-site-version PR still brings the stamp onto main. Check for an existing tag before stamping, and accept one that is HEAD or the stamp commit on top of HEAD, so rerunning the bot for a version that is already tagged reuses the tag rather than failing on a fresh stamp commit. Update MIGRATION.md (Steps 12-14) to match, including merging the stamp PR with Squash and merge, since its bot commit is unsigned. Co-Authored-By: Claude Opus 5.5 Signed-off-by: Bill Traynor --- .github/workflows/version-bot.yml | 50 ++++++++++++++++++++----------- CHANGELOG.md | 8 +++++ MIGRATION.md | 42 +++++++++++++++----------- 3 files changed, 66 insertions(+), 34 deletions(-) diff --git a/.github/workflows/version-bot.yml b/.github/workflows/version-bot.yml index 90ad26b..359759f 100644 --- a/.github/workflows/version-bot.yml +++ b/.github/workflows/version-bot.yml @@ -162,15 +162,40 @@ jobs: # time is then wiped by the next push to main, which rebuilds the whole # site without it. See build-pages-site.sh, step 3. # - # Pushing to main can be refused (branch protection, or main moved - # since checkout). That must not fail the release, so on refusal we - # drop the stamp and leave it to build-pdf.yml's stamp-site-version - # job, which opens a PR as before -- the site version then lags until - # that PR merges, exactly as it did previously. + # Pushing to main can be refused: branch protection, or main moved + # since checkout, or -- the normal case in the riscv organization -- a + # ruleset requiring signed commits and a passing DCO check, which a + # bot's direct push can never satisfy. That must not fail the release. + # On refusal we KEEP the stamp commit and tag it anyway, pushing only + # the tag: rulesets and branch protection apply to branches, so the + # tag still lands, and it still carries a descriptor naming its own + # version. The stamp commit then lives only on the tag, not on main; + # build-pdf.yml's stamp-site-version job opens a PR to bring the same + # stamp onto main. Until that merges, main builds as `dev` as usual, + # and the release keeps its own /// path. git config user.name "riscv-gitbot" git config user.email "actions@users.noreply.github.com" + + # A rerun for a version that is already tagged (say, after its build + # failed) reuses the tag rather than stamping again. Accept the tag + # when it is HEAD itself or the stamp commit made on top of HEAD by an + # earlier run whose push to main was refused; anything else means the + # version was cut from different content. + tag_exists=false + if git rev-parse -q --verify "refs/tags/$next" >/dev/null; then + tag_sha="$(git rev-list -n1 "$next")" + head_sha="$(git rev-parse HEAD)" + tag_parent="$(git rev-parse -q --verify "$tag_sha^" || true)" + if [[ "$tag_sha" != "$head_sha" && "$tag_parent" != "$head_sha" ]]; then + echo "Tag $next already exists on another commit ($tag_sha)." >&2 + exit 1 + fi + echo "Tag $next already exists for HEAD ($tag_sha); reusing." + tag_exists=true + fi + stamp_committed=false - if [[ "$REF_NAME" == "main" ]]; then + if [[ "$tag_exists" == "false" && "$REF_NAME" == "main" ]]; then ./scripts/stamp-antora-version.sh "$next" "$(date +%Y-%m-%d)" if git diff --quiet -- antora.yml; then echo "antora.yml already names $next; nothing to stamp." @@ -184,22 +209,13 @@ jobs: stamp_committed=true echo "Stamped antora.yml to $next on $REF_NAME before tagging." else - echo "::warning::Could not push the antora.yml stamp to $REF_NAME; leaving it to the stamp PR. The site keeps the previous version until that PR merges." - git reset -q --hard "origin/$REF_NAME" + echo "::notice::Could not push the antora.yml stamp to $REF_NAME; tagging the stamp commit instead, so $next still carries its own version. The stamp PR brings the same change onto $REF_NAME." fi fi fi echo "stamp_committed=$stamp_committed" >> "$GITHUB_OUTPUT" - if git rev-parse -q --verify "refs/tags/$next" >/dev/null; then - tag_sha="$(git rev-list -n1 "$next")" - head_sha="$(git rev-parse HEAD)" - if [[ "$tag_sha" != "$head_sha" ]]; then - echo "Tag $next already exists on another commit ($tag_sha)." >&2 - exit 1 - fi - echo "Tag $next already exists on HEAD; reusing." - else + if [[ "$tag_exists" == "false" ]]; then git tag -a "$next" -m "Automated version tag for $(git rev-parse HEAD)" git push origin "$next" fi diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b20ee5..bfb8bde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 **_NOTE:_** PROJECTS BUILT USING THE TEMPLATE SHOULD UPDATE THE BELOW SECTIONS AS-NEEDED. ## [Unreleased] +- Keep the version stamp on the release tag when `main` refuses the bot's + push. The `riscv` organization ruleset requires signed commits and a passing + DCO check on the default branch, so `version-bot.yml`'s pre-tag push of the + `antora.yml` stamp is refused in every `riscv` repository. The bot used to + discard the stamp and tag the unstamped commit, so the release's versioned + site path was dropped by the next push to `main`. It now tags the stamp + commit and pushes only the tag, which the ruleset does not cover. A rerun + for an already-tagged version reuses the tag instead of failing. - Stop `template-sync.yml` from overwriting `GOVERNANCE.md`. The template's copy is a placeholder every task group rewrites, and `UPGRADING.md` already said to treat an amended copy as a shared file, but the workflow copied it diff --git a/MIGRATION.md b/MIGRATION.md index 04d0d8e..3a96e9c 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -494,13 +494,19 @@ file. naming its own version. That is what lets the Pages build publish the release under `///` and keep it there: a tag stamped afterwards never qualifies (see `scripts/build-pages-site.sh`, step 3), so - the next push to `main` rebuilds the site without it. -- [ ] Sync the upstream `build-pdf.yml` `stamp-site-version` job too. It is now - the **fallback**: if the pre-tag push is refused — branch protection, or - `main` moved since checkout — it opens a review PR titled - `Stamp Antora site version vX.Y to match released PDF`, which you merge to - bring the site version back in line. It is monotonic, and it skips - silently when `main` is already stamped, which is the normal case. + the next push to `main` rebuilds the site without it. If `main` refuses + the push, the bot tags the stamp commit instead and pushes only the tag, + so the tag carries its own version either way. +- [ ] Sync the upstream `build-pdf.yml` `stamp-site-version` job too. It is the + **fallback** for when the pre-tag push is refused — branch protection, + `main` moved since checkout, or, in every `riscv` repository, the + organization ruleset that requires signed commits and a passing DCO check + on the default branch, which a bot's direct push never satisfies. It opens + a review PR titled `Stamp Antora site version vX.Y to match released PDF` + that brings the stamp onto `main`. Its commit is the bot's and unsigned, so + merge it with **Squash and merge**: GitHub signs the squash commit, while a + merge commit would be refused. It is monotonic, and it skips silently when + `main` is already stamped. - [ ] Verify: ```bash make stamp-antora VERSION=v0.8 DATE=2026-06-12 @@ -607,12 +613,13 @@ else depends on it. `v--` path — that is deliberate, and the exact commit is still shown on the cover page. -> **One version, not a dropdown.** The build publishes the checked-out ref, plus -> any release tag whose `antora.yml` names that same tag. Under the standard -> release flow the tag is cut *before* the stamp PR from Step 12 merges, so no -> tag carries its own version and exactly one version is published. Tags that -> predate your Antora migration are skipped with a reason rather than aborting -> the build — Antora fails hard on any ref lacking `antora.yml`. +> **Which versions are published.** The build publishes the checked-out ref, plus +> any release tag whose `antora.yml` names that same tag. The version bot stamps +> before it tags (Step 12), so every release cut by the bot qualifies and the +> site grows a version per release. Tags cut before that — including any cut by +> an older `version-bot.yml` whose stamp push was refused — name some other +> version and are skipped with a reason, as are tags that predate your Antora +> migration (Antora fails hard on any ref lacking `antora.yml`). --- @@ -629,10 +636,11 @@ When you're ready to advance to the next milestone: ARC convention. - [ ] **If the release opened a site version stamp PR** (`Stamp Antora site version vX.Y to match released PDF`), review and merge - it. Normally there is none: the release stamps `antora.yml` on `main` - before tagging, and the PR appears only when that push was refused. Until - it merges, the site version lags the released PDF, and the release has no - versioned path of its own. The values are generated from + it with **Squash and merge**. It appears whenever the bot's push to `main` + was refused, which in `riscv` repositories is every release. The release + itself is unaffected — the tag already carries the stamp, so the site + publishes it under its own versioned path — but until the PR merges, `main` + still names the previous version. The values are generated from `release-info.sh`, so this wants a merge, not an edit. - [ ] After it merges, confirm the site renders at `///` with a cover reading `Version vX.Y, YYYY-MM-DD: ` — identical to the