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