Skip to content

feat(ship): roll CHANGELOG [Unreleased] into a dated section on every release#491

Merged
githubrobbi merged 1 commit into
mainfrom
feat/ship-roll-changelog
Jun 29, 2026
Merged

feat(ship): roll CHANGELOG [Unreleased] into a dated section on every release#491
githubrobbi merged 1 commit into
mainfrom
feat/ship-roll-changelog

Conversation

@githubrobbi

Copy link
Copy Markdown
Collaborator

Why

The changelog drift fixed wholesale in #490 had a root cause: just ship bumped the workspace version but never touched CHANGELOG.md, so ## [Unreleased] silently accumulated already-shipped work and every release in between went unrecorded. This makes the ship flow self-maintaining so it can't drift again.

What

  • New changelog module (scripts/ci-pipeline/src/changelog.rs) — pure, unit-tested roll_unreleased(content, version, date):
    • moves the ## [Unreleased] body under a fresh dated ## [vX.Y.Z] header
    • leaves an empty ## [Unreleased] for the next cycle
    • repoints the Keep-a-Changelog footer compare-links ([Unreleased]vNEW...HEAD, adds [vNEW]vPREV...vNEW)
  • Wired into Phase 2 right after bump_workspace_version, before git_commit (git add .), so the rolled changelog lands in the same signed release commit. Gated by version_incremented and itself a no-op on an already-rolled file → resumed ships never double-roll.
  • Soft no-ops: a missing CHANGELOG.md or an empty ## [Unreleased] skip cleanly (no empty sections); only a changelog with no ## [Unreleased] header at all is an error.
  • 6 unit tests: roll, empty no-op, idempotent re-run, missing-header error, footer-less roll, header parse.

Lint-clean under the full strict workspace stack (.get()/iterators, no unwrap/expect/panic, every item documented).

🤖 Generated with Claude Code

… release

The drift fixed wholesale in #490 had a root cause: `just ship` bumped the
workspace version but never touched CHANGELOG.md, so `## [Unreleased]`
silently accumulated already-shipped work and every release in between went
unrecorded. This makes the ship flow self-maintaining so it cannot drift again.

- New `changelog` module in the ci-pipeline crate: pure, unit-tested
  `roll_unreleased(content, version, date)` moves the `## [Unreleased]` body
  under a fresh dated `## [vX.Y.Z]` header, leaves an empty `## [Unreleased]`
  for the next cycle, and repoints the Keep-a-Changelog footer compare-links
  ([Unreleased] -> vNEW...HEAD, adds [vNEW] -> vPREV...vNEW).
- Wired into Phase 2 right after `bump_workspace_version`, before `git_commit`
  (`git add .`), so the rolled changelog lands in the same signed release
  commit. Gated by `version_incremented` and itself a no-op on an
  already-rolled file, so resumed ships never double-roll.
- Soft no-ops: a missing CHANGELOG.md or an empty `## [Unreleased]` skip
  cleanly (no empty sections); only a changelog with no `## [Unreleased]`
  header at all is an error.
- 6 unit tests: roll, empty no-op, idempotent re-run, missing-header error,
  footer-less roll, header parse.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@githubrobbi githubrobbi enabled auto-merge June 29, 2026 04:21
@githubrobbi githubrobbi added this pull request to the merge queue Jun 29, 2026
Merged via the queue into main with commit f6aab89 Jun 29, 2026
21 checks passed
@githubrobbi githubrobbi deleted the feat/ship-roll-changelog branch June 29, 2026 04:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant