changelog
Procedure
- Find the range:
git describe --tags --abbrev=0→ last tag. If no tags, use the first commit or ask. Range =<last-tag>..HEAD. - Collect:
git log --no-merges --format='%h %s' <range>. For each commit, read the subject; open the diff only when the subject is unclear (git show --stat <sha>). - Map Conventional Commit types → sections:
feat→Added,fix→Fixed,perf/refactor→Changed,deprecate→Deprecated,remove→Removed,security/fix(security)→Security. Ignorechore,ci,test,docsunless user-visible. - Write user-facing lines (what changed for the user, not how). One line per commit or per logical group; reference PR/issue numbers when present in the subject (
(#123)). - If
CHANGELOG.mdexists, insert under## [Unreleased](create the heading if missing) without touching older entries. If it does not exist, create it with the Keep a Changelog header. - If the user is cutting a version: rename
[Unreleased]→[X.Y.Z] - YYYY-MM-DD, add a fresh empty[Unreleased], and propose (do not run)git tag -a vX.Y.Z -m "...". - Show the diff of CHANGELOG.md.
Rules
- Every line traces to a commit in the range. No invented entries.
- Breaking changes get a BREAKING: prefix and go first in their section.
- Do not bump
package.json/pyproject.tomlversions unless asked.
Eval
evals/changelog/: fixture with tag v0.1.0 and 5 commits after it (2 feat, 1 fix, 1 chore, 1 feat!: breaking); expected: chore omitted, breaking first with prefix, entries under [Unreleased].