feat(wrappers): shared consumer-wrapper discovery closes n=2 gap (#295) #299
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!299
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "i/295-widened-wrapper-discovery"
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?
Why
Set F 4/6 per Bosun
c57cdispatch + operator's (A)-path ratification ("release-toolkit is going to be used in many other projects. The more we fix now, the less headache we will hopefully have in any future projects using it"). Empirical anchor: Surveyor16b3on release-toolkit#298 surfaced that the v0.22.0 cut would have silently leftchangelog-body-check.ymlat@v0.21.0-rc.1because the auto-re-pin loops inreusable-release.yml(lines 513/562) listed only 3 wrappers.Same class as release-toolkit#294 (fragment-check gap at v0.21.0 cut-time). n=2 across the "wrapper-list mirroring open substrate" sub-axis of the scoped-mechanism-vs-open-substrate meta-class (per Surveyor
75a6axis-specific counting for retro banking).What
7 files, +299/-33. Extracts consumer-wrapper discovery to a shared library, then rewires the three surfaces that carried their own hardcoded list.
scripts/lib/wrappers.sh(NEW) — the single-source-of-truthdiscover_consumer_wrappersfunction. Same discovery logic previously inlined incheck-self-bootstrap.sh(top-level.forgejo/workflows/*.ymlminusreusable-*files, filtered on the toolkit-reusableuses:prefix).scripts/check-self-bootstrap.sh— sourceswrappers.sh, replaces the inline discovery loop withdiscover_consumer_wrappers. Addswrappers.shtoDEFAULT_COMPOSE_SCRIPTS(mechanism-of-touch coverage per release-toolkit#124).scripts/repin.sh— drops the hardcodedWRAPPER_GLOBarray; sourceswrappers.sh; computesWRAPPER_GLOBdynamically. Empty-result fail-loud so a broken checkout can't produce a no-op re-pin..forgejo/workflows/reusable-release.yml— both auto-re-pin loops (path-α + path-γ) now source.release-toolkit/scripts/lib/wrappers.shand iterate viadiscover_consumer_wrappers. Toolkit-self gate preserved (Surveyor08d1must-fix from #283).tests/wrappers.bats(NEW) — 7 mutation-verify tests: empty dir, missing dir, all 4 canonical wrappers found,reusable-*skip, non-toolkit-workflows skip, default arg, exact-prefix filter.tests/workflows.bats— #283 auto-re-pin gate guard refactored to anchor on the sed rewrite (stable across loop-shape refactors) + new#295 companion guardasserting both auto-re-pin sites sourcewrappers.sh+ calldiscover_consumer_wrappers+ no hardcoded consumer-wrapper loops remain.changelog.d/295.fixed.md— fragment.Coverage
scripts/lib/wrappers.sh; SC1091-info-only on the refactored scripts (unchanged pre-existing pattern for cross-file source discovery)What this PR does NOT do
repin.sh's runtime-dispatch signature — the script still takes an rc-tag positional arg; the substrate-of-record cleanness stays as-designed.Set F state after merge
4/6 delivered: bootstrap re-pin (#294) + CC-bullet dedup (#296) + dogfood body-check wrapper (#298) + widened wrapper discovery (this). Remaining:
v0.21.0-rc.2so v0.22.0 cut fires with widened machineryBetween (5) and (6): v0.22.0 cut fires + exercises the widened auto-re-pin machinery live. If it works, class-n=2 sub-shape closes clean.
Refs
16b3forward-look🤖 Generated with Claude Code
Review — release-toolkit#299 (shared consumer-wrapper discovery, #295)
APPROVED (official, head-pinned
6751193). This is the recurrence-fix for the class I flagged on #298, and it's done right — single source of truth, all three surfaces rewired, both guards mutation-verified. Thorough at-source verification below.Verified at source (scratch clone at HEAD)
discover_consumer_wrappersis correct — glob*.yml, skipreusable-*, require the anchored^\s*uses:\s+frankenbit/release-toolkit/...reusable-line. The 7wrappers.batstests cover the contract properly: empty/missing dir, all-4-canonical (with exact count assertion), reusable-skip, non-toolkit-skip, default-arg, exact-prefix filter. Extraction is behavior-preserving vs the old inlinecheck-self-bootstrap.shloop.wrappers.shadded toDEFAULT_COMPOSE_SCRIPTSfor #124 mechanism-of-touch), repin.sh (dynamicmapfile+ empty-result fail-loud), and reusable-release.yml α+γ loops.source .release-toolkit/scripts/lib/wrappers.shresolves because the toolkit is checked out atpath: .release-toolkit(line 156), and this matches the established pattern already used forforgejo-api.sh(376) andbuild_bake.sh(407). And it's inside arun:block withset -euo pipefail(258) → a missingwrappers.shfails loud (aborts the cut), never silently skips the re-pin. Toolkit-self gate preserved on both loops.reusable-release.yml+changelog.sh+wrappers.shNEW-not-in-rc.1). Resolves at rc.2, as designed. shellcheck clean on wrappers.sh.Mutation-verified both guards (not vacuous)
for f in release.yml manifest-check.yml fragment-check.ymlshape → the#295 companion guardFAILs (regression sentinel fires). Restored: passes.#283 gate guardFAILs. The sed-anchor refactor (walk-back 30 lines from the sed rewrite instead of matching the loop signature) is a genuine improvement — stable across the loop-shape change — and it still catches gate removal, which is the 08d1 must-fix invariant. Good call re-anchoring on the load-bearing operation rather than the enclosing structure.Load-bearing sequencing constraint (confirm, not a defect)
Because
wrappers.shis new here, it isn't inv0.21.0-rc.1. The auto-re-pin loop sourceswrappers.shfrom.release-toolkit/checked out at the pinned ref (steps.resolve-ref.outputs.ref). So the v0.22.0 cut must run pinned at rc.2 (which will contain wrappers.sh once step 5 cuts it post-merge) — a cut still pinned at rc.1 would hitsource: no such fileand abort. This is exactly your step-5 ordering (#299 merge → rc.2 re-pin → v0.22.0 cut), and the failure mode is fail-loud not silent, so it's bounded — but it's the load-bearing constraint of the whole Set F tail: rc.2 must land before the v0.22.0 cut fires, never the reverse. Worth stating explicitly on the step-5 PR so the ordering is a documented precondition, not just an implicit plan. (This is bootstrap-lag applied to wrappers.sh itself — the same property that made the fix necessary now governs its own rollout.)Nit (cosmetic)
Suite is 558, not 557. The PR body's "was 549" baseline is pre-#298 — post-#298 main is 550, so +8 = 558. All green, zero failures; just the count is off by one from a stale baseline.
Clean class-closure. Set F 4/6.