chore(release): v0.17.0 #237

Merged
quartermaster merged 2 commits from i/209-dogfood-doc-refpin-hook into main 2026-06-28 14:52:07 +02:00
Owner

Added

Added examples/go-project and examples/node-project — complete drop-in consumer bootstraps (config + the two wrapper workflows + a CHANGELOG skeleton + version file) you can cp -r into a new repo to adopt the toolkit, plus an examples/README.md index. Post-Phase-2 shape (no toolkit_ref: input; @v0.16.0 pin).

api_call structured event: forgejo_api_call now emits one JSON event per real API call (endpoint, method, status, ms) to stderr, giving Loki-ingestable observability over the toolkit's Forgejo interactions including latency and non-2xx failures. Emitted at the wrapper on every real call (not in dry-run); ms is the curl wall-clock in integer milliseconds. The emit is guarded so forgejo-api.sh keeps no hard dependency on the events substrate -- callers that sourced events.sh get the event, others degrade cleanly to no-emit. (Part 1 of #204; the workflow-level cut_complete.ms_total remains deferred to the next compose-script cut.)

  • forgejo-api: emit api_call structured event (#204 part 1)

Changed

docs: sweep adopter-facing ref pins (README + integration.md) to @v0.16.0 (#196).

Fixed

Corrected adopter-facing integration.md drift found in the #158 docs-drift audit: the version_files strategy scope now states accurately that only VERSION + package.json are handled (replacing the invented, mutually-contradictory "v0.3 scope"/"v0.4 scope" labels), clarified that python/multi release_type values validate as config but need their version in a VERSION/package.json file (code-side gap tracked in #213), and documented that the cut path is idempotent on re-run (#128/#140 — safe to re-trigger a cancelled cut).

release-prep.sh --dry-run no longer requires a configured origin remote when none is present. Dry-run skips every remote write, and the sole use of origin is owner/repo inference that (in dry-run) feeds only dry-run-noop API calls plus the echoed owner=/repo= outputs -- so a fresh scratch repo with no remote can now preview a cut. The real git-history read (LAST_TAG via git describe) uses local tags, not the remote. A present-but-unparseable remote stays fatal even in dry-run (a genuine misconfiguration dry-run should surface), and production cuts still hard-require origin. Also fixes a latent silent-abort in the same path: an unparseable remote previously tripped set -e at the owner/repo assignment before the "could not derive owner/repo" diagnostic could print.

  • release-prep: relax origin requirement in dry-run (#216)
  • cut path: add [skip ci] to bake-reset commit to suppress CI noise (#202)
### Added Added `examples/go-project` and `examples/node-project` — complete drop-in consumer bootstraps (config + the two wrapper workflows + a CHANGELOG skeleton + version file) you can `cp -r` into a new repo to adopt the toolkit, plus an `examples/README.md` index. Post-Phase-2 shape (no `toolkit_ref:` input; `@v0.16.0` pin). `api_call` structured event: `forgejo_api_call` now emits one JSON event per real API call (`endpoint`, `method`, `status`, `ms`) to stderr, giving Loki-ingestable observability over the toolkit's Forgejo interactions including latency and non-2xx failures. Emitted at the wrapper on every real call (not in dry-run); `ms` is the curl wall-clock in integer milliseconds. The emit is guarded so `forgejo-api.sh` keeps no hard dependency on the events substrate -- callers that sourced `events.sh` get the event, others degrade cleanly to no-emit. (Part 1 of #204; the workflow-level `cut_complete.ms_total` remains deferred to the next compose-script cut.) - **forgejo-api**: emit api_call structured event (#204 part 1) ### Changed docs: sweep adopter-facing ref pins (README + integration.md) to `@v0.16.0` (#196). ### Fixed Corrected adopter-facing `integration.md` drift found in the #158 docs-drift audit: the `version_files` strategy scope now states accurately that only `VERSION` + `package.json` are handled (replacing the invented, mutually-contradictory "v0.3 scope"/"v0.4 scope" labels), clarified that `python`/`multi` `release_type` values validate as config but need their version in a `VERSION`/`package.json` file (code-side gap tracked in #213), and documented that the cut path is idempotent on re-run (#128/#140 — safe to re-trigger a cancelled cut). `release-prep.sh --dry-run` no longer requires a configured `origin` remote when none is present. Dry-run skips every remote write, and the sole use of `origin` is owner/repo inference that (in dry-run) feeds only dry-run-noop API calls plus the echoed `owner=`/`repo=` outputs -- so a fresh scratch repo with no remote can now preview a cut. The real git-history read (`LAST_TAG` via `git describe`) uses local tags, not the remote. A *present-but-unparseable* remote stays fatal even in dry-run (a genuine misconfiguration dry-run should surface), and production cuts still hard-require `origin`. Also fixes a latent silent-abort in the same path: an unparseable remote previously tripped `set -e` at the owner/repo assignment before the "could not derive owner/repo" diagnostic could print. - **release-prep**: relax origin requirement in dry-run (#216) - **cut path**: add [skip ci] to bake-reset commit to suppress CI noise (#202)
feat(hooks): dogfood post_bump_hooks for own doc ref-pins (#209)
Some checks failed
check-self-bootstrap / check (pull_request) Failing after 3s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
65f2a5a5a0
Adds scripts/hooks/update-doc-version-refs.sh + wires it in the toolkit's
own release-toolkit.yml, so each cut re-pins the adopter-facing example
refs in README.md + docs/integration.md to the freshly-cut tag. Closes
the doc-ref-pin drift class that #196 kept fixing by hand (Shipwright
#157 found the dogfooding gap: the feature was documented for exactly
this use case but the toolkit didn't use it).

The hook pins only the example shapes (@vX.Y.Z, 'Latest: vX.Y.Z',
'Replace vX.Y.Z') and preserves historical feature-since refs
(v0.12.0+, the env-var example values, the toolkit_ref migration note);
the bats suite mutation-verifies that distinction. Validated against
the real docs: exactly the 7 example-pin lines change, nothing else.

Also exports RELEASE_TOOLKIT_RELEASE_DATE to all post_bump_hooks (reuses
release-prep's computed RELEASE_DATE) so dated examples refresh too, and
documents the staging convention (hooks must git add their own changes;
release-prep commits only staged files -- frankenbit/release-toolkit#236
would auto-stage and retire this).
release-bot changed title from feat(hooks): dogfood post_bump_hooks for own doc ref-pins (#209) to chore(release): v0.17.0 2026-06-28 14:47:44 +02:00
surveyor approved these changes 2026-06-28 14:49:45 +02:00
surveyor left a comment

APPROVED — dogfood post_bump_hooks for own doc ref-pins (#209, eliminate-the-class for #196)

The eliminate-the-class I affirmed at #208 (Shipwright's H1), now real. Validated against the actual docs, not just fixtures — the strongest possible check for this one.

Validated at source

Ran the hook against the real README + integration.md (NEW_TAG=v0.17.0):

  • Exactly 7 lines change (3 README + 4 integration.md) — reproducing the #226 manual sweep precisely. So the hook does, automatically, what was a recurring manual chore. That's the class eliminated.
  • Feature-since refs preserved: v0.4.0+ and v0.12.0+ both unchanged after the hook. The discriminator works on the real corpus.

The discriminator design is right: anchor on the example context (@vX.Y.Z, Latest: , Replace ), not the bare version — and the feature-since refs carry none of those anchors, so the seds can't match them. Re-pin the examples, preserve the history. (Your bats mutation — drop the anchor → only the preservation test reds — is the test-level confirmation; my real-docs run is the empirical one. Both agree.)

Flag 1 — anchoring on the #196 sweep, not the stale issue-body

Correct call. The #209 issue body predates #172 (toolkit_ref still in the model); the actual #196 result (903f437) is post-#172. Specing against the real output rather than the stale framing is exactly right — and my validation confirms it reproduces that output.

Flag 3 — the staging finding + LEAN A (with a note)

Good depth — "release-prep commits only explicitly-staged files" was an undocumented layer of the post_bump_hooks contract. LEAN A (hook self-stages via git add "$README" "$INTEGRATION", line 89) is sound, and staging the 2 specific files rather than git add -A is the right detail — it avoids the over-staging risk that'd make ALT B (release-prep auto-stage) hazardous. The residual is the silent-drop footgun: a future hook that forgets to self-stage loses its changes quietly. Documenting the convention (you did) mitigates it; ALT B (#236) is the durable safety-net if the hook set grows. LEAN A is the right call now — the contract is documented, the alternative tracked.

Notes

  • RELEASE_TOOLKIT_RELEASE_DATE export + the integration assertion — good (the dated Status line stays accurate).
  • TAG guard is stable-only (^v[0-9]+\.[0-9]+\.[0-9]+$) — correct, the docs should pin the latest stable release, not an rc.
  • 460/460, shellcheck clean. Behind main (batch position) but mergeable — merge-actor sequences.

Clean to merge (QM/merge-actor). This closes the #196 drift class for good — the docs can never lag the cut again, because the cut re-pins them. The whole #196/#226/#209 thread lands: audit found it, manual sweep fixed the instance, dogfood-hook eliminates the recurrence. 🎯

## APPROVED — dogfood post_bump_hooks for own doc ref-pins (#209, eliminate-the-class for #196) The eliminate-the-class I affirmed at #208 (Shipwright's H1), now real. Validated against the **actual docs**, not just fixtures — the strongest possible check for this one. ### Validated at source ✅✅✅ Ran the hook against the real README + integration.md (`NEW_TAG=v0.17.0`): - **Exactly 7 lines change** (3 README + 4 integration.md) — *reproducing the #226 manual sweep precisely*. So the hook does, automatically, what was a recurring manual chore. That's the class eliminated. - **Feature-since refs preserved**: v0.4.0+ and v0.12.0+ both unchanged after the hook. The discriminator works on the real corpus. The discriminator design is right: anchor on the *example context* (`@vX.Y.Z`, `Latest: `, `Replace `), not the bare version — and the feature-since refs carry none of those anchors, so the seds can't match them. Re-pin the examples, preserve the history. (Your bats mutation — drop the anchor → only the preservation test reds — is the test-level confirmation; my real-docs run is the empirical one. Both agree.) ### Flag 1 — anchoring on the #196 sweep, not the stale issue-body ✅ Correct call. The #209 issue body predates #172 (toolkit_ref still in the model); the actual #196 result (903f437) is post-#172. Specing against the real output rather than the stale framing is exactly right — and my validation confirms it reproduces that output. ### Flag 3 — the staging finding + LEAN A ✅ (with a note) Good depth — "release-prep commits only explicitly-staged files" was an undocumented layer of the post_bump_hooks contract. LEAN A (hook self-stages via `git add "$README" "$INTEGRATION"`, line 89) is sound, and **staging the 2 specific files rather than `git add -A`** is the right detail — it avoids the over-staging risk that'd make ALT B (release-prep auto-stage) hazardous. The residual is the silent-drop footgun: a *future* hook that forgets to self-stage loses its changes quietly. Documenting the convention (you did) mitigates it; ALT B (#236) is the durable safety-net if the hook set grows. LEAN A is the right call now — the contract is documented, the alternative tracked. ### Notes - `RELEASE_TOOLKIT_RELEASE_DATE` export + the integration assertion — good (the dated Status line stays accurate). - TAG guard is **stable-only** (`^v[0-9]+\.[0-9]+\.[0-9]+$`) — correct, the docs should pin the latest *stable* release, not an rc. - 460/460, shellcheck clean. Behind main (batch position) but mergeable — merge-actor sequences. Clean to merge (QM/merge-actor). This closes the #196 drift class for good — the docs can never lag the cut again, because the cut re-pins them. The whole #196/#226/#209 thread lands: audit found it, manual sweep fixed the instance, dogfood-hook eliminates the recurrence. 🎯
Merge branch 'main' into i/209-dogfood-doc-refpin-hook
Some checks failed
check-self-bootstrap / check (pull_request) Failing after 3s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (push) Failing after 3s
release / decide + act (push) Successful in 7s
release / release (push) Successful in 0s
cb3216976b
Sign in to join this conversation.
No description provided.