chore(release): v0.30.0 #447
No reviewers
Labels
No labels
bump
major
bump
minor
bump
patch
kind/bug
kind/chore
kind/docs
kind/feature
priority/critical
priority/high
priority/low
priority/medium
size/L
size/M
size/S
size/XL
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit!447
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "release-prep/rolling"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Added
Cut-time preflight verifies the composed CHANGELOG section is gate-clean before the release fires. A new
scripts/compose-verify.shruns at the top of thecutcase inreusable-release.yml. It scans the target section withregister-check --stdinandchangelog-body-check.The preflight blocks the cut when either gate flags drift or density. Closes the gap surfaced by PR#438 (v0.28.0), where a manifest-only recovery skipped the auto push:main trigger and workflow_dispatch fired the cut against a CHANGELOG that never went through compose. No action required for adopters — the preflight is wired into the reusable workflow. Closes #439.
Changed
None.
Deprecated
None.
Removed
None.
Fixed
check-self-bootstrapno longer fires red on the rolling-PR-merge push:main event. The auto-re-pin substrate (#283) runs INSIDE the cut workflow that fires on that same push, so the pin-drift check saw pre-cut state and reported a false-positive RED. The check now detects a HEAD subject matching the release-prep merge shape and skips with an informative message.Discipline preserved for every OTHER push:main. A hand-edit to
release.yml, an orphaned tag, or any content edit outside the rolling-PR flow still fires the check. Closes the "check-self-bootstrap RED on every substrate cut" class (empirical: PR#438 v0.28.0 arc + PR#443/#446 Bundle 1/2 sprint). No action required. Closes #445.release-prep.shnow scaffolds all 6 standard CHANGELOG sections in the composed body. When fragments produce only a subset (e.g., onlyAdded+Fixed), the missing sections are filled withNone.before the section transitions intoCHANGELOG.md. Aligns compose to the documentedchangelog-body-checkcheck-2 intent ("add each even if the body is 'None.'").Closes the compose-vs-check-2 divergence surfaced by the v0.30.0 rolling PR, which would otherwise block at cut-time via the compose-verify preflight. Idempotent: existing sections pass through verbatim; running twice produces identical output. Non-standard sections (e.g., a fragment producing
### Internal) are preserved after the standard set. No action required. Closes #453.Surveyor — empirical-validation pass (first cut through the Bundle 1/2/3 arc)
Ran the full validation on live at head
5de77c3a, using the exact pinned reusable versions CI runs (@v0.29.0scripts), not PR-head or the green/red CI proxy. The cut is blocked — two independent, reproduced defects. Seven of nine checks are green; the two reds are both real (not flakes/staleness), and this is exactly the class of interaction the validation surface exists to catch.Finding A —
changelog-body-checkcheck 2 (composed section missing mandatory sections) → tracked in #453The composed
## [v0.30.0]has only### Added+### Fixed; check 2 requires all six canonical sections. This is a delayed consequence of #440: its newest-versioned selector shipped in v0.29.0, and v0.30.0 is the first prep PR to run a reusable (@v0.29.0) that carries it — so check 2 now fires on the composed versioned section instead of the empty[Unreleased]it used to skip. compose emits only fragment-backed sections and never scaffolds emptyNone.sections, so the two disagree. Full mechanism + fix-space (Option A recommended: compose scaffolds all six) in #453. Blocks the PR gate andcompose-verifyat cut-time.Finding B —
register-checkfile-scan drift → fix in #452 (under review)tests/compose-verify.bats:83carried chamber-name attribution that the pinnedv0.29.0scanner flags. This is not a scrub miss and not a review miss — the currentregister-check.shhardcode-excludes that fixture (:151, added ina83379d), so head/main scans clean; only the version-pinned scanner (tagged56bf27b, before the exclusion existed) trips it. It's the self-referential-fixture / pinned-scanner-lag class. #452 addresses it; see review 3682 for the fix-shape (allow-list the fixture rather than scrub it, so the load-bearing#439 primarytest keeps its drift).The third red is expected, not a defect
check-self-bootstrapis green here (the prep subject triggers the #449 skip). On non-prep PRs it's currently red on the standing pin-drift (main'sreusable-release.ymlcarries #446 ahead of thev0.29.0pin) — the normal cut-window state, clears on tag + re-pin.Disposition
Not machine-mergeable as-is. Suggested order: land #452 (adjusted per 3682) so main is register-clean → decide #453 (Option A as a v0.30.0 must-fix, or defer to v0.30.1) → PR#447 recomposes on the next
push:main. Both reds have owners and trackers; nothing here is silent.The validation pass did its job: it caught a real delayed-coupling defect (A) and confirmed a pinned-scanner-lag (B) before v0.30.0 shipped on them.
— Surveyor
5de77c3a851e3329645f1e3329645f50130600a8Surveyor — post-#452/#454 recompose result (follow-up to the empirical-validation pass)
Both defect fixes are merged to
main(#452 @ register-allowlist, #454 @ compose scaffold). I re-ran the validation on the recomposed PR#447 head50130600(base = currentmain41a33255), using the pinned versions CI actually runs. The cut is still blocked — one of the two reds cleared, the other did not, and the one that did not is instructive.Finding B (register drift) — RESOLVED ✓
Pinned
v0.29.0register-check full-tree over the recomposed tree → 0 hits. #452's.register-allowlistentry fortests/compose-verify.batsis inherited frommain, and it's read at scan time by the pinned scanner. Clean.Finding A (check 2 / missing sections) — NOT yet resolved for the cut ✗
The recomposed
## [v0.30.0]section still has only### Added+### Fixed(2 headers).changelog-body-checkcheck 2 fails on the pinnedv0.29.0scanner (missingChanged Removed Deprecated Upgrade), and CI agrees (changelog-body-check / checkred).Why #454 didn't take effect here — the pinned-tooling-lag class catching its own fix:
main'sscripts/release-prep.sh+scripts/lib/changelog.sh(verified: 1 scaffold call + 1 def on41a33255).release.yml:56→reusable-release.yml@v0.29.0. That reusable's baked toolkit ref isv0.29.0(resolve-refsource=baked), so it checks outrelease-toolkit@v0.29.0and runs thatrelease-prep.sh— which has 0 scaffold calls (the scaffold is new in #454, post-dating thev0.29.0tag).main. #454's fix cannot reach the recompose until the reusable is re-pinned to a version that carries it — and that re-pin happens as part of a cut, which is exactly what check 2 is blocking.This is the meta-tracker #448 class ("pinned-scanner/tooling-lag on the first cut after a toolkit change") applied recursively: the fix for the compose-vs-check-2 divergence is itself gated behind the pinned recompose. It's the inherent "first cut carrying a compose-affecting fix must be bootstrapped past its own gate" property — not a defect in #454, which is correct on
main.Unblock options (owner's call — QM/Engineer)
None.sections to PR#447's## [v0.30.0]body so check 2 + compose-verify pass, then fire the cut. The cut re-pins the reusable tov0.30.0(which carries the scaffold), and every subsequent recompose self-scaffolds. Caveat: the manual scaffold is fragile against an interveningpush:main— a recompose before the cut would re-runrelease-prep@v0.29.0and overwrite the body back to 2 headers. So the cut must fire before the next recompose (or hold other merges tomainin that window).release.yml'suses:at a moving/newer ref so the recompose runsmain's scaffold-carryingrelease-prep. Cleaner conceptually but un-pins the reusable — I'd only take this if (A)'s race window is a real problem.Both fixes are correct on
main; the remaining work is purely the bootstrap past the pinned gate. Once v0.30.0 cuts, #448's reliably-green criterion starts accumulating on the post-bootstrap cuts (the ones that run the scaffold-carrying reusable), which is where the empirical evidence is load-bearing anyway.— Surveyor
50130600a8071e318888APPROVED — PR#447 @
071e3188(v0.30.0 cut, recomposed through the re-pinned flow)The empirical-validation arc closes green. The composed v0.30.0 body is gate-clean end-to-end, verified on live with the
@v0.30.0-rc.2==maintooling CI now runs. This stamp satisfies branch-protection for the operator's merge → cut.Composed body — all gates pass
Added / Changed / Fixed / Removed / Deprecated / Upgrade, with the empties (Changed,Removed,Deprecated,Upgrade) scaffolded toNone.— the #454 scaffold firing through the re-pinnedrelease-prep.changelog-body-checkcheck 2 → clean (all standard sections present). The Finding-A block is resolved for the actual cut, not just onmain.register-checkfull-tree → 0 hits. #452's allowlist entry inherited; no drift.compose-verify→OK: compose-verify preflight passed for [v0.30.0]. Both gates the cut runs at preflight are green, so the cut won't block at compose-time.This is #453 AC(d) met end-to-end: a subset-of-sections release now composes a check-2-clean, compose-verify-green body.
Two soft warnings — non-gating, accepted ship-as-is
changelog-body-checkexits 0 (passed with warnings):Fixedsection is mixed bullet+prose (bullets=3, prose=4) — a natural artifact of substrate-heavy bundles (paragraph closures for #439/#445/#453 + register/tests/compose sub-item bullets).Both are cosmetic and neither gates the cut. Ship-as-is is the right call (confirmed with QM) — a recompose-to-normalize would shift the head + cost another re-verify + operator time for a cosmetic win, against the established "shipped-with-warns > delayed-by-cosmetic-refinement" bar.
The bootstrap, verified
This cut is the reference implementation of the #448 fix-cut-bootstrap-through-own-gate handling: #454's scaffold couldn't reach the recompose while pinned
@v0.29.0(comment #80816), so Option C bakedv0.30.0-rc.2(tooling byte-identical tomain, self-referential baked ref — reviewed at PR#455), re-pinned the wrappers, and this recompose ran the scaffold-carrying tooling. Class-1 (check-self-bootstrap) self-healed at the re-pin (PR#455 was 7/7 green); Class-3 (compose scaffold) self-healed here, one cadence later — the staggered bootstrap edges the unifying class predicts.Clean to merge → v0.30.0 cuts. First clean cut through the Bundle 1/2/3 arc; #448's post-bootstrap reliably-green evidence starts accumulating on the cut this produces.
— Surveyor