chore(release): v0.3.0 #25

Merged
alex merged 3 commits from release-prep/v0.3.0 into main 2026-06-24 20:48:53 +02:00

Added

  • post_bump_hooks: [path] config lets consumers register hook scripts that fire AFTER version_files are bumped + BEFORE the git commit. Used for per-consumer bookkeeping that doesn't belong in the toolkit's general flow (updating a --version example in README to match the cut, regenerating versioned docs, syncing vendored manifests). Each hook is an executable script invoked from the consumer repo root + receives RELEASE_TOOLKIT_NEW_VERSION + RELEASE_TOOLKIT_NEW_TAG + RELEASE_TOOLKIT_PREVIOUS_TAG env vars. Zero exit → release-prep continues; non-zero exit aborts the cut with the hook's stderr propagated (no commit, no push, no PR). Multiple hooks run in declaration order; first failure aborts the chain. Hook paths are operator-controlled (no injection risk) and properly arg-quoted (paths with spaces are safe). See docs/integration.md for the full mechanics + safety surfaces. Fourth v0.3 / release-toolkit#4 slice (4 of 5).

  • pre_v1_breaking_to_minor config flag (opt-in) lets pre-1.0 projects in settling-shape express "breaking change" semantically (in commits or fragments) without triggering the major-version commitment that 1.0+ implies. Set pre_v1_breaking_to_minor: true in release-toolkit.yml to downgrade majorminor bumps while the manifest is 0.x.y. Once the project crosses 1.0.0, the flag silently becomes a no-op — major bumps survive as major. Default false (strict SemVer); the policy is opt-in via the config flag. See docs/conventions.md for mechanics + semver_apply_pre_v1_policy for the implementation. First v0.3 / release-toolkit#4 slice (1 of 5).

  • section_format: { tag_prefix, separator } config lets consumers customize the CHANGELOG.md section heading shape. Defaults match Keep a Changelog's example (## [vX.Y.Z] - YYYY-MM-DD); consumers can override either or both fields independently. Empty string for tag_prefix is a meaningful opt-out that drops the v-prefix (## [X.Y.Z] — matches tmux-tell's existing shape); separator: " — " switches to em-dash. The heading is constructed as ## [<tag_prefix><X.Y.Z>]<separator><DATE>. changelog_transition gains 2 new optional positional params (5th = TAG_PREFIX, 6th = SEPARATOR) with ${var-default} (not ${var:-default}) semantics so explicit empty string is preserved. See docs/integration.md for examples + the missing-vs-empty semantic distinction. Third v0.3 / release-toolkit#4 slice (3 of 5).

  • docs/migration/tmux-tell.md migration guide — step-by-step migration walkthrough for projects with tmux-tell's substrate shape (Go projects with no VERSION file, build-time version injection via -ldflags, pre-1.0 BREAKING-as-minor discipline, em-dash CHANGELOG headings, per-consumer release-time bookkeeping). Covers: tmux-tell-shape release-toolkit.yml config; 4 consumer-side workflow wrappers; the README pin-update hook script with the post_bump_hooks env-var contract; trust-model checkpoint (branch-protect the hook + the config); one-cycle parity check before retiring the old workflow chain. Generalizes to any pre-1.0 Go project with similar shape; cellblock's node-strategy migration doesn't need any of these flags. Fifth + final v0.3 / release-toolkit#4 slice (5 of 5).

  • version_files: [] accepted as a valid config — opts into tag-is-version mode where git describe --tags is the authoritative version source. The lockstep check in manifest-check.sh step 2 emits SKIP rather than failing; step 4 (tag-vs-manifest) treats the git tag as its own manifest (no comparison required). release-prep.sh does NOT bump any files when configured this way; the new version propagates via the CHANGELOG transition + the tag at release-draft + publish. Distinguishes "field missing" (defaults to VERSION per v0.1 behavior) from "field explicitly empty" (tag-is-version opt-in). Right shape for Go projects with -ldflags version injection (tmux-tell + similar) and projects where the tag IS the source of truth. See docs/integration.md for the config example. Second v0.3 / release-toolkit#4 slice (2 of 5).

  • release-prep: post_bump_hooks config + execution — #4 slice 4/5

  • config,changelog: section_format custom heading shape — #4 slice 3/5

  • config: version_files: [] accepted (tag-is-version mode) — #4 slice 2/5

  • scripts/lib: pre_v1_breaking_to_minor config opt-in (closes #4 slice 1/5)

### Added - **`post_bump_hooks: [path]` config** lets consumers register hook scripts that fire AFTER `version_files` are bumped + BEFORE the git commit. Used for per-consumer bookkeeping that doesn't belong in the toolkit's general flow (updating a `--version` example in README to match the cut, regenerating versioned docs, syncing vendored manifests). Each hook is an executable script invoked from the consumer repo root + receives `RELEASE_TOOLKIT_NEW_VERSION` + `RELEASE_TOOLKIT_NEW_TAG` + `RELEASE_TOOLKIT_PREVIOUS_TAG` env vars. Zero exit → release-prep continues; non-zero exit aborts the cut with the hook's stderr propagated (no commit, no push, no PR). Multiple hooks run in declaration order; first failure aborts the chain. Hook paths are operator-controlled (no injection risk) and properly arg-quoted (paths with spaces are safe). See [`docs/integration.md`](docs/integration.md#post-bump-hooks-post_bump_hooks) for the full mechanics + safety surfaces. Fourth v0.3 / release-toolkit#4 slice (4 of 5). - **`pre_v1_breaking_to_minor` config flag** (opt-in) lets pre-1.0 projects in settling-shape express "breaking change" semantically (in commits or fragments) without triggering the major-version commitment that 1.0+ implies. Set `pre_v1_breaking_to_minor: true` in `release-toolkit.yml` to downgrade `major` → `minor` bumps **while the manifest is 0.x.y**. Once the project crosses 1.0.0, the flag silently becomes a no-op — major bumps survive as major. Default `false` (strict SemVer); the policy is opt-in via the config flag. See [`docs/conventions.md`](docs/conventions.md#pre-10-opt-in-pre_v1_breaking_to_minor) for mechanics + `semver_apply_pre_v1_policy` for the implementation. First v0.3 / release-toolkit#4 slice (1 of 5). - **`section_format: { tag_prefix, separator }` config** lets consumers customize the CHANGELOG.md section heading shape. Defaults match Keep a Changelog's example (`## [vX.Y.Z] - YYYY-MM-DD`); consumers can override either or both fields independently. Empty string for `tag_prefix` is a meaningful opt-out that drops the v-prefix (`## [X.Y.Z]` — matches tmux-tell's existing shape); `separator: " — "` switches to em-dash. The heading is constructed as `## [<tag_prefix><X.Y.Z>]<separator><DATE>`. `changelog_transition` gains 2 new optional positional params (5th = TAG_PREFIX, 6th = SEPARATOR) with `${var-default}` (not `${var:-default}`) semantics so explicit empty string is preserved. See [`docs/integration.md`](docs/integration.md#custom-section-format-section_format) for examples + the missing-vs-empty semantic distinction. Third v0.3 / release-toolkit#4 slice (3 of 5). - **`docs/migration/tmux-tell.md` migration guide** — step-by-step migration walkthrough for projects with tmux-tell's substrate shape (Go projects with no `VERSION` file, build-time version injection via `-ldflags`, pre-1.0 BREAKING-as-minor discipline, em-dash CHANGELOG headings, per-consumer release-time bookkeeping). Covers: tmux-tell-shape `release-toolkit.yml` config; 4 consumer-side workflow wrappers; the README pin-update hook script with the post_bump_hooks env-var contract; trust-model checkpoint (branch-protect the hook + the config); one-cycle parity check before retiring the old workflow chain. Generalizes to any pre-1.0 Go project with similar shape; cellblock's node-strategy migration doesn't need any of these flags. Fifth + final v0.3 / release-toolkit#4 slice (5 of 5). - **`version_files: []` accepted** as a valid config — opts into tag-is-version mode where `git describe --tags` is the authoritative version source. The lockstep check in `manifest-check.sh` step 2 emits `SKIP` rather than failing; step 4 (tag-vs-manifest) treats the git tag as its own manifest (no comparison required). `release-prep.sh` does NOT bump any files when configured this way; the new version propagates via the CHANGELOG transition + the tag at release-draft + publish. Distinguishes "field missing" (defaults to `VERSION` per v0.1 behavior) from "field explicitly empty" (tag-is-version opt-in). Right shape for Go projects with `-ldflags` version injection (tmux-tell + similar) and projects where the tag IS the source of truth. See [`docs/integration.md`](docs/integration.md#tag-is-version-mode-version_files-) for the config example. Second v0.3 / release-toolkit#4 slice (2 of 5). - **release-prep**: post_bump_hooks config + execution — #4 slice 4/5 - **config,changelog**: section_format custom heading shape — #4 slice 3/5 - **config**: version_files: [] accepted (tag-is-version mode) — #4 slice 2/5 - **scripts/lib**: pre_v1_breaking_to_minor config opt-in (closes #4 slice 1/5)
Generated by release-toolkit release-prep.sh.

Tracker: frankenbit/release-toolkit#1
docs(CHANGELOG): clean up v0.3.0 section per substrate-care discipline
All checks were successful
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 4s
manifest-check / check (pull_request) Successful in 0s
cd3605e224
The auto-generated v0.3.0 cut emitted:
1. The 5 long-form fragments in alphabetical-by-filename order
   (post_bump_hooks → pre-v1 → section_format → tmux-tell → version_files)
   instead of slice number (1-5).
2. Duplicate commit-subject bullets at the end of ### Added that
   restate what the long-form fragment prose above already says.
   Same pattern as the v0.2.1 cut + same toolkit-sanctioned manual
   dedupe per docs/conventions.md "No deduplication in v0.1;
   review prep PR + dedupe manually if it matters."

## Cleanup

- Reordered the 5 fragments by slice number (1 → 5: pre_v1_breaking
  → version_files → section_format → post_bump_hooks → migration doc)
  so a reader following the v0.3 sprint sequence finds them in
  the natural order
- Dropped the 4 duplicate commit-subject bullets at the end of
  ### Added (the long-form fragment prose IS the canonical
  CHANGELOG entry; the commit-subject form was the conventional-
  commits-categorize layer producing a parallel summary)
- Added a 2-paragraph framing intro under the version heading
  naming the sprint scope (5 config additions + migration guide)
  and the substantive milestone (first fully-dogfooded MINOR cut)

Substrate-honest disclosure: the framing intro paragraphs are
HAND-WRITTEN, not derived from a fragment. The toolkit's auto-
generated section was structurally complete but missed the
sprint-level narrative that makes the section legible to a
future reader who didn't watch the day unfold.

No code changes from the auto-cut; CHANGELOG narrative only.

Tracker: frankenbit/release-toolkit#4 (v0.3 sprint cut cleanup)
docs(CHANGELOG): fix config-additions count in v0.3.0 intro (4 not 5)
Some checks failed
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 4s
manifest-check / check (pull_request) Successful in 0s
release-draft / create Forgejo draft release (pull_request) Failing after 4s
release-draft / draft (pull_request) Failing after 0s
ff328f697b
Per Surveyor 5862 nit: intro said "5 config additions + migration
guide" but there are 4 config additions (pre_v1, version_files,
section_format, post_bump_hooks) + 1 migration guide. The migration
guide isn't a config addition. Corrected to "4 config additions +
a migration guide."

Substance unchanged; count-phrasing fix only.
alex merged commit ff328f697b into main 2026-06-24 20:48:53 +02:00
alex deleted branch release-prep/v0.3.0 2026-06-24 20:48:53 +02:00
Sign in to join this conversation.
No description provided.