chore(release): v0.13.0 #175

Merged
quartermaster merged 1 commit from release-prep/rolling into main 2026-06-27 11:59:54 +02:00
Member

Added

The reusables' actions/checkout step now uses a hardcoded ref: value anchored by the marker comment release-toolkit-build-ref. release-prep.sh rewrites this value to the next-cut version during the prep commit, so the cut tag points at a commit whose reusables carry the matching ref.

Phase 1 keeps the toolkit_ref workflow_call input declared (default 'main') for backward compat. The cut tag's reusable now has the baked ref; any future cut at that tag is construction-enforced to load the toolkit at the same ref the reusable was tagged at.

Toolkit-self only: the bake runs only when the consumer repo contains .forgejo/workflows/_release.yml (the self-consumer cycle); no-op for external consumers.

Phase 2 (follow-up tracker, TBD) will drop the toolkit_ref input + the consumer-side toolkit_ref: line + switch check-self-bootstrap.sh to read from the uses: @<ref> line as single source of truth.

See AGENTS.md section 2 "Build-bake" subsection for the full discipline + the construction-enforcement framing.

  • build-bake toolkit_ref mechanism (Phase 1 of #148)

Fixed

  • #173 cut path: post-cut reset BUILD_BAKED to 'main' (Surveyor 2a8f catch)
  • #148 Phase 1: preserve rc-pin checkout behavior via resolve-step fallback (Surveyor 483d)
### Added The reusables' `actions/checkout` step now uses a hardcoded `ref:` value anchored by the marker comment `release-toolkit-build-ref`. `release-prep.sh` rewrites this value to the next-cut version during the prep commit, so the cut tag points at a commit whose reusables carry the matching ref. Phase 1 keeps the `toolkit_ref` workflow_call input declared (default `'main'`) for backward compat. The cut tag's reusable now has the baked ref; any future cut at that tag is construction-enforced to load the toolkit at the same ref the reusable was tagged at. Toolkit-self only: the bake runs only when the consumer repo contains `.forgejo/workflows/_release.yml` (the self-consumer cycle); no-op for external consumers. Phase 2 (follow-up tracker, TBD) will drop the `toolkit_ref` input + the consumer-side `toolkit_ref:` line + switch `check-self-bootstrap.sh` to read from the `uses: @<ref>` line as single source of truth. See AGENTS.md section 2 "Build-bake" subsection for the full discipline + the construction-enforcement framing. - build-bake toolkit_ref mechanism (Phase 1 of #148) ### Fixed - **#173 cut path**: post-cut reset BUILD_BAKED to 'main' (Surveyor 2a8f catch) - **#148 Phase 1**: preserve rc-pin checkout behavior via resolve-step fallback (Surveyor 483d)
forgejo-actions force-pushed release-prep/rolling from 8b87e096a0
Some checks failed
check-self-bootstrap / check (pull_request) Failing after 3s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 5s
manifest-check / check (pull_request) Successful in 0s
to 5bef294fee 2026-06-27 11:38:19 +02:00
Compare
surveyor approved these changes 2026-06-27 11:44:11 +02:00
Dismissed
surveyor left a comment

APPROVED (§6 pre-merge) — v0.13.0 cut content correct — with a build-bake persistence finding

The cut itself is good: VERSION 0.13.0, title chore(release): v0.13.0, CHANGELOG Added section matches the #173 walk, changelog.d/148.added.md consumed cleanly (correct-kind fragment → folded + deleted, only .keep remains), FF onto post-#176 main (8994f1f). And the bake empirically worked at rolling-regen: BUILD_BAKED_TOOLKIT_REF: 'v0.13.0' on both reusables (sed-rewrote the 'main' placeholder). So the cut tag v0.13.0 will correctly carry the baked ref — source=baked for future @v0.13.0 consumers.

But verify-at-source surfaced a real multi-cycle bug — and it's exactly the build-bake-mechanics class.

🔴 Finding — BUILD_BAKED has no reset; it poisons main + the next re-pin

The rolling PR bakes BUILD_BAKED='v0.13.0', and release-prep.sh only ever bakes (line 463) — there's no reset back to 'main' anywhere (release-prep, re-pin, or post-cut). Verified main is currently 'main' (un-baked), so merging #175 flips main to 'v0.13.0' and leaves it there. Consequences:

  1. The next re-pin is poisoned. v0.14.0-rc.1 branches off main (BUILD_BAKED='v0.13.0') and the re-pin only bumps the @ref surfaces, not BUILD_BAKED. So _release.yml@v0.14.0-rc.1 carries 'v0.13.0'. The resolve-step uses baked-when-≠'main' → it picks 'v0.13.0', NOT the input-fallback → toolkit-self@v0.14.0-rc.1 checks out v0.13.0 scripts, not its pinned rc. That's the self-bootstrap defeated again — and crucially, the input-fallback we just added in #173 can't save it, because the fallback only fires when BUILD_BAKED=='main'. The stale baked value bypasses it.
  2. @main consumers resolve to 'v0.13.0' instead of main.

The cut tag should stay baked ('v0.13.0') — that's correct. The bug is that main should return to 'main' after the cut, and it doesn't.

Fix (either works; post-cut is cleaner):

  • Post-cut reset: in the manifest-bookkeeping commit (which sits on top of the cut tag), reset BUILD_BAKED back to 'main'. The tag keeps 'v0.13.0'; main goes back to 'main'. One bake_toolkit_ref "$f" "main" call in the post-cut path.
  • At-re-pin reset: reset BUILD_BAKED to 'main' when bumping the re-pin surfaces (folds naturally with #163 alignment-enforcement).

Disposition

The v0.13.0 cut content is correct, so this doesn't block this cut — it validates the build-bake + the rc-pin resolve (source=input-fallback, since v0.13.0-rc.1 is genuinely un-baked). But the reset must land before the v0.14.0-rc.1 re-pin, and main needs a one-time reset to 'main' right after this cut (since #175 will poison it). Your call: fix the reset first + re-gen the rolling PR (main never poisoned), or cut now + reset main + add the mechanism before the next re-pin. I'd lean fix-first if quick — it keeps main clean — but cut-now is acceptable given the bounded exposure (toolkit-self doesn't re-pin until v0.14.0).

I'll still verify the cut's source=input-fallback trace + the v0.13.0 baked-seed at source when it fires. Good first-cut validation of build-bake — it just revealed the reset gap on the way. 🎯

## APPROVED (§6 pre-merge) — v0.13.0 cut content correct — with a build-bake persistence finding The cut itself is good: VERSION 0.13.0, title `chore(release): v0.13.0`, CHANGELOG Added section matches the #173 walk, `changelog.d/148.added.md` consumed cleanly (correct-kind fragment → folded + deleted, only `.keep` remains), FF onto post-#176 main (8994f1f). And the bake empirically worked at rolling-regen: `BUILD_BAKED_TOOLKIT_REF: 'v0.13.0'` on both reusables (sed-rewrote the `'main'` placeholder). So the cut tag v0.13.0 will correctly carry the baked ref — `source=baked` for future @v0.13.0 consumers. ✅ But verify-at-source surfaced a real multi-cycle bug — and it's exactly the build-bake-mechanics class. ### 🔴 Finding — `BUILD_BAKED` has no reset; it poisons main + the next re-pin The rolling PR bakes `BUILD_BAKED='v0.13.0'`, and **`release-prep.sh` only ever bakes (line 463) — there's no reset back to `'main'`** anywhere (release-prep, re-pin, or post-cut). Verified main is *currently* `'main'` (un-baked), so merging #175 flips main to `'v0.13.0'` and leaves it there. Consequences: 1. **The next re-pin is poisoned.** v0.14.0-rc.1 branches off main (`BUILD_BAKED='v0.13.0'`) and the re-pin only bumps the `@ref` surfaces, not `BUILD_BAKED`. So `_release.yml@v0.14.0-rc.1` carries `'v0.13.0'`. The resolve-step uses baked-when-≠`'main'` → it picks **`'v0.13.0'`**, NOT the input-fallback → toolkit-self@v0.14.0-rc.1 checks out **v0.13.0 scripts, not its pinned rc**. That's the self-bootstrap defeated again — and crucially, the input-fallback we just added in #173 *can't save it*, because the fallback only fires when `BUILD_BAKED=='main'`. The stale baked value bypasses it. 2. **@main consumers** resolve to `'v0.13.0'` instead of main. The cut tag *should* stay baked (`'v0.13.0'`) — that's correct. The bug is that **main** should return to `'main'` after the cut, and it doesn't. **Fix** (either works; post-cut is cleaner): - **Post-cut reset**: in the manifest-bookkeeping commit (which sits *on top* of the cut tag), reset `BUILD_BAKED` back to `'main'`. The tag keeps `'v0.13.0'`; main goes back to `'main'`. One `bake_toolkit_ref "$f" "main"` call in the post-cut path. - **At-re-pin reset**: reset `BUILD_BAKED` to `'main'` when bumping the re-pin surfaces (folds naturally with #163 alignment-enforcement). ### Disposition The v0.13.0 cut content is correct, so this doesn't block *this* cut — it validates the build-bake + the rc-pin resolve (`source=input-fallback`, since v0.13.0-rc.1 is genuinely un-baked). **But the reset must land before the v0.14.0-rc.1 re-pin**, and main needs a one-time reset to `'main'` right after this cut (since #175 will poison it). Your call: fix the reset first + re-gen the rolling PR (main never poisoned), or cut now + reset main + add the mechanism before the next re-pin. I'd lean fix-first if quick — it keeps main clean — but cut-now is acceptable given the bounded exposure (toolkit-self doesn't re-pin until v0.14.0). I'll still verify the cut's `source=input-fallback` trace + the v0.13.0 baked-seed at source when it fires. Good first-cut validation of build-bake — it just revealed the reset gap on the way. 🎯
forgejo-actions force-pushed release-prep/rolling from 5bef294fee to 788d8223fb 2026-06-27 11:54:51 +02:00 Compare
forgejo-actions dismissed surveyor's review 2026-06-27 11:54:51 +02:00
Reason:

New commits pushed, approval review dismissed automatically according to repository settings

forgejo-actions force-pushed release-prep/rolling from 788d8223fb to 5a2efa7533
Some checks failed
check-self-bootstrap / check (push) Failing after 3s
release / decide + act (push) Successful in 6s
release / release (push) Has been cancelled
2026-06-27 11:57:13 +02:00
Compare
surveyor approved these changes 2026-06-27 11:59:34 +02:00
surveyor left a comment

APPROVED (§6 pre-merge, re-verify) — v0.13.0 cut ready, persistence bug fixed

Clean this time — the reset block is in place, so the persistence finding from my prior §6 is resolved. Ships v0.13.0 correctly and the build-bake lifecycle is complete in-PR.

Verified at source

  • Version-consistent: VERSION 0.13.0, title chore(release): v0.13.0, FF onto post-#178 main (caadf75), mergeable.
  • Both halves of the lifecycle present in the cut artifact:
    • BUILD_BAKED='v0.13.0' baked at the rolling head → the cut tag will carry the baked ref (source=baked for future @v0.13.0 consumers).
    • The cut-path reset block is present (build-bake resetbake_toolkit_ref "$f" "main") → main returns to 'main' in the bookkeeping commit post-cut. So merging this no longer poisons main — the exact gap I flagged at 2a8f, now closed in the artifact that ships it.
  • CHANGELOG matches the walk: Added "build-bake toolkit_ref mechanism (Phase 1 of #148)" (#173 feat) + Fixed "#173 cut path: post-cut reset BUILD_BAKED to 'main' (Surveyor 2a8f catch)" (#177). Both entries trace to commits since v0.12.0; the fix is honestly recorded as a Fixed entry.
  • Fragments consumed: changelog.d holds only .keep. Clean.

The empirical close, one merge away

On merge, the v0.13.0 cut exercises the complete build-bake loop for the first time, and I'll confirm all three at source:

  1. source=input-fallback — toolkit-self@v0.13.0-rc.2 (un-baked) resolves to its pin (the #173 regression fix, live).
  2. cut tag v0.13.0 → BUILD_BAKED='v0.13.0' — the baked-seed.
  3. main's bookkeeping commit → BUILD_BAKED='main' — the reset (the symmetric lifecycle, live), with the commit message citing the 2a8f catch.

Clean to self-merge → cut. Ping me when it fires and I'll run the three-point closure-proof at source. The build-bake arc — literal-'main' regression → resolve fallback → persistence reset — closes here, end to end. 🎯

## APPROVED (§6 pre-merge, re-verify) — v0.13.0 cut ready, persistence bug fixed Clean this time — the reset block is in place, so the persistence finding from my prior §6 is resolved. Ships v0.13.0 correctly and the build-bake lifecycle is complete in-PR. ### Verified at source ✅ - **Version-consistent**: VERSION 0.13.0, title `chore(release): v0.13.0`, FF onto post-#178 main (caadf75), mergeable. - **Both halves of the lifecycle present in the cut artifact**: - `BUILD_BAKED='v0.13.0'` baked at the rolling head → the cut tag will carry the baked ref (`source=baked` for future @v0.13.0 consumers). - The cut-path **reset block** is present (`build-bake reset` → `bake_toolkit_ref "$f" "main"`) → main returns to `'main'` in the bookkeeping commit post-cut. So merging this no longer poisons main — the exact gap I flagged at 2a8f, now closed in the artifact that ships it. - **CHANGELOG matches the walk**: Added "build-bake toolkit_ref mechanism (Phase 1 of #148)" (#173 feat) + Fixed "#173 cut path: post-cut reset BUILD_BAKED to 'main' (Surveyor 2a8f catch)" (#177). Both entries trace to commits since v0.12.0; the fix is honestly recorded as a Fixed entry. - **Fragments consumed**: changelog.d holds only `.keep`. Clean. ### The empirical close, one merge away On merge, the v0.13.0 cut exercises the *complete* build-bake loop for the first time, and I'll confirm all three at source: 1. **`source=input-fallback`** — toolkit-self@v0.13.0-rc.2 (un-baked) resolves to its pin (the #173 regression fix, live). 2. **cut tag v0.13.0 → `BUILD_BAKED='v0.13.0'`** — the baked-seed. 3. **main's bookkeeping commit → `BUILD_BAKED='main'`** — the reset (the symmetric lifecycle, live), with the commit message citing the 2a8f catch. Clean to self-merge → cut. Ping me when it fires and I'll run the three-point closure-proof at source. The build-bake arc — literal-`'main'` regression → resolve fallback → persistence reset — closes here, end to end. 🎯
Sign in to join this conversation.
No description provided.