Skip to content

feat(changelog): auto-draft [Unreleased] from commits (hybrid draft + polish)#523

Merged
githubrobbi merged 1 commit into
mainfrom
feat/changelog-autodraft-from-commits
Jul 4, 2026
Merged

feat(changelog): auto-draft [Unreleased] from commits (hybrid draft + polish)#523
githubrobbi merged 1 commit into
mainfrom
feat/changelog-autodraft-from-commits

Conversation

@githubrobbi

Copy link
Copy Markdown
Collaborator

The durable fix for the stale-changelog problem. The roll only ever moved a hand-authored [Unreleased] into a dated section — but nobody kept [Unreleased] filled, so 0.6.19–0.6.22 shipped blank. This makes it a hybrid: a draft is generated from Conventional-Commit subjects, so it's never blank, and it's polished by hand when convenient.

What it does

  • generate_commit_draft()git log <last-tag>..HEAD → classify subjects (feat→Added, fix→Fixed, perf/refactor→Changed; ci/chore/build/style/docs/test dropped; !**Breaking:** prefix) → grouped Keep-a-Changelog body, chronological.
  • Ship fallback — when [Unreleased] is empty, roll_changelog_file rolls the generated draft instead of "nothing to roll." A release is never blank. Hand-authored [Unreleased] still wins when present.
  • just changelog-draft (new ChangelogDraft subcommand) — populate [Unreleased] with the draft on demand, to polish before shipping. Never overwrites hand-authored notes.

Verified

Live-ran against the real history — produced a clean grouped draft (Added: the feat, Fixed: the fixes with scopes + PR links, chore/docs dropped). Pure classify/roll/inject logic is unit-tested (5 new). No new dependency.

The workflow now

Draft is always there as a placeholder → polish into narrative once in a while → ship rolls whatever's there. Can't silently go stale again.

… polish)

The changelog roll only ever *moved* a hand-authored [Unreleased] into a dated
section; nobody kept [Unreleased] filled, so releases shipped blank (0.6.19-
0.6.22 went unrecorded). This makes it a hybrid: a draft is generated from the
Conventional-Commit subjects since the last release tag, so there is always
something better than nothing, and it is polished by hand when convenient.

- generate_commit_draft(): `git log <last-tag>..HEAD` -> classify subjects
  (feat->Added, fix->Fixed, perf/refactor->Changed; ci/chore/build/style/docs/
  test dropped; `!` -> **Breaking:** prefix) -> grouped Keep-a-Changelog body.
- Ship fallback: when [Unreleased] is empty, roll_changelog_file rolls the
  generated draft instead of "nothing to roll" — a release is never blank.
  Hand-authored [Unreleased] still wins when present.
- `just changelog-draft` (ChangelogDraft subcommand): populate [Unreleased]
  with the draft on demand, to polish before shipping. Never overwrites
  hand-authored notes.

Pure classification + roll + inject logic is unit-tested; verified end-to-end
against the real history (produces a clean grouped draft). No new dependency.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@githubrobbi githubrobbi enabled auto-merge July 4, 2026 13:36
@githubrobbi githubrobbi added this pull request to the merge queue Jul 4, 2026
Merged via the queue into main with commit 320629e Jul 4, 2026
21 checks passed
@githubrobbi githubrobbi deleted the feat/changelog-autodraft-from-commits branch July 4, 2026 13:52
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