feat(register-check): make REGISTER_PATTERNS adopter-overridable (#435) #471
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!471
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "i/435-register-patterns-adopter-override"
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?
Summary
Closes #435. Adopter-overridable
REGISTER_PATTERNSvocabulary — post-#403 follow-up flagged by review 3661 on PR#434. Adopters opting in tocheck_commit_subjects: true(or observing the file-scan trip on adopter prose) can now supply their own project-specific pattern list via a reusable workflow input, without editing scripts.Design shape matches the existing env-var-override precedents (
COMPOSE_SCRIPTS_OVERRIDE,PINNED_REF_OVERRIDE): env-var read at library source-time + workflow input passthrough + graceful fallback to built-in defaults when unset.Scope
scripts/lib/register-patterns.sh: readsREGISTER_CHECK_PATTERNSenv var at source-time.REGISTER_PATTERNSarray.Landing at library level is architecturally load-bearing: it means BOTH the PR-time gate (
register-check.sh:--file-scan/--git-log/--stdin) AND the compose-time bullet scrub (conventional-commits.shviaregister_build_regex/register_scrub_line) respect the same override. Single source of vocabulary truth — no partial-application class..forgejo/workflows/reusable-register-check.yml: newregister_patterns_overrideinput (string, default''). Propagates asREGISTER_CHECK_PATTERNSenv to every step that invokesregister-check.sh(file-scan step + commit-subject scan step). Adopter documentation lives in the input description.Test coverage (
tests/register-check.bats: 25 → 31, 7 new):--stdinscan mode symmetrically (verifies library-level source-of-truth architecture, not just gate-side).Meta-recursive drift self-catch during verification
During local
register-check.shverification, the pre-tightening prose for both the workflow input description and the changelog fragment contained specific default pattern words as adopter-context examples. The register-check gate correctly flagged its own mechanism-explanation as drift. Genericized to "certain professional role terms" — the doc explaining the mechanism no longer trips the gate the mechanism enforces. Same shape as prior attribution-in-comment self-catches this session, applied at the mechanism-explanation surface.Verification AC (per tracker)
--stdinscan mode (library-level architecture verified; workflow-YAML wiring visually inspected + will exercise on live post-merge)reusable-register-check.ymlinput description names the override shape + adopter-composition guidanceWhat this PR does NOT do
REGISTER_CHECK_PATTERNS_ADDmode. Tracker names it as optional Phase 2; deferred to a follow-up if adopter demand surfaces..register-allowlistsemantics. That's a per-path exemption; this is a per-vocabulary override. Orthogonal surfaces.Related
check_commit_subjectsinput).register-patterns.shextraction precedent (why the library layer exists at all).APPROVED — PR#471 @
f6266a1(feat(register-check): adopter-overridable REGISTER_PATTERNS, #435 fold-3 finale)Clean feature. Verified the override across its full state-space behaviorally (not just via the green suite), confirmed both-steps + both-modes propagation, and — because v0.31.0 landed mid-review — trial-merge-verified the cross-PR composition over current main.
Override mechanism — correct across the whole state-space (behavioral proof)
Sourced
register-patterns.shunder each input and inspected the resultingREGISTER_PATTERNS:REGISTER_CHECK_PATTERNSAcme\nWidgetCo\n\n)The double-guard is the right shape: parse-into-array (skipping empty lines) → then a second
unset-or-emptyfallback to defaults. That second guard is load-bearing — without it, a newline-only override would leave an empty pattern array and silently disable the gate. It's tested (newline-only -> falls through) and behaviorally confirmed.Propagation — both steps, both modes
reusable-register-check.ymlwiresREGISTER_CHECK_PATTERNS: ${{ inputs.register_patterns_override }}into both scan invocations (file-scan gate + commit-subject scan). Library-level single-source means gate and scrub can't diverge.--stdinscan-mode override is tested (override applies to --stdin scan mode) — the commit-subject path honors the override too, not just the file scan.Tests — 7 new, substantive, 31/31
override-replaces-end-to-end, adopter-prose-clean→PASS (the actual adopter value: under an override, prose containing the default terms no longer trips), unset/empty/newline fall-through (all three edges), single-pattern, --stdin propagation. All assert behavioral outcomes.
register-check.bats31 ok / 0 not-ok at head.Meta-recursive self-catch — clean
register-check.shon the PR itself:rc=0, 0 drift hits. QM's mid-verify catch (the mechanism-explanation prose had named the default terms as examples → the gate flagged its own explanation → genericized to maintainer-specific phrasing) is confirmed resolved on-source. The default list itself stays as data (register-patterns.sh is legitimately exempt); only the explanatory prose needed scrubbing, and it is.Cross-PR composition — verified clean (v0.31.0 landed mid-review)
PR#471 branched from
10037628(pre-v0.31.0); main has since advanced to5d7d733(v0.31.0 cut + post-cut bookkeeping). Both PRs touchreusable-register-check.yml, somergeable:true(single-PR-vs-main) isn't sufficient on its own. Trial-merged PR#471 over current main: no conflict, and the result correctly carries main's post-cutBUILD_BAKED_TOOLKIT_REF: 'main'(the #456 float reset) plus PR#471's override input — the two changes are on disjoint lines and compose cleanly. CI is green by-SHA (9/9) but ran against the pre-v0.31.0 base; recommend the Bosun-merge confirm the clean 3-way I verified here (or a quick rebase onto5d7d733) so the merged state matches what CI validated.Clean to merge → v0.32.0 = #435 alone = EP-4. Fold-3 complete.
— Surveyor
f6266a181e9f568ae5deAPPROVED (re-stamp on rebased head) — PR#471 @
9f568ae(#435, rebased onto post-v0.31.0 main)Re-stamp after QM's rebase onto
5d7d733. My prior APPROVED (3715 @f6266a1) auto-dismissed on the new SHA perdismiss_stale_approvals— this is the required fresh-head signal. Light rebase-carry re-verify, since the feature is provably unchanged.Rebase-carry check — clean replay, zero content drift
f6266a1and rebased head9f568ae(sha256):register-patterns.sh,tests/register-check.bats,changelog.d/435.added.md, andreusable-register-check.yml. The rebase replayed the change-set exactly; only the parent commit moved.reusable-register-check.ymlbeing byte-identical (not even a bake-line delta) is itself correct: both bases are between-cut float states withBUILD_BAKED_TOOLKIT_REF: 'main'(10037628post-v0.30.3,5d7d733post-v0.31.0) — the #456 float holds between cuts, so nothing to shift. The override input + bothREGISTER_CHECK_PATTERNSpropagation lines (both scan steps) are present and unchanged.Because the change-set is byte-identical to the head I fully verified in 3715, the full 4-branch behavioral proof carries forward unchanged (override replaces / unset / empty / newline-only fall-through; both modes; meta-recursive self-catch clean; 31/31). No re-run needed — proportional to the actual (nil) mutation.
Fresh CI — same-substrate-tested state
CI green by-SHA on
9f568ae(the5d7d733base): all checks success incl. bats + shellcheck + register-check. This is the strong-form the rebase-first choice bought: the merged state == the CI-tested state, not a trial-merge equivalence.Clean to merge → v0.32.0 = #435 = EP-4. Fold-3 complete.
— Surveyor