Generate or update the CHANGELOG.md Unreleased section from commits since the latest release tag.
Generate or update the CHANGELOG.md Unreleased section from commits since the latest release tag.
Check if a .jj directory exists at the repository root.
.jj exists — use jj commandsgit commandsFind the latest release tag:
git tag --sort=-creatordate | head -1
Get all commits between the latest release tag and HEAD:
jj:
jj log -r 'tags()..@' --no-graph -T 'description ++ "\n"'
git:
git log <latest-tag>..HEAD --format="%H %s" --reverse
Ignore commits with type docs, chore, style, ci, build, or revert — these are housekeeping
and should not appear in user-facing changelogs. Also ignore merge commits.
For each commit that references an issue (e.g. Closes #42 in footer, or issue number in the branch),
look up the issue title to write a user-friendly description.
For commits tied to a GitHub Issue, append the issue as a parenthetical at the end of the entry
(e.g. (see [#42])), where [#42] is a reference-style link to the GitHub issue.
For commits not tied to an issue, do not add a reference.
For each commit, look up the author's GitHub username. Use the commit SHA to query:
gh api repos/{owner}/{repo}/commits/{sha} --jq '.author.login'
If the author is not the repository owner, add by @username attribution to the entry (see step 5).
Commits by the repository owner do not need attribution.
Map each commit to a Keep a Changelog category based on the conventional commit type:
| Commit type | Changelog section |
|---|---|
feat | Added |
fix | Fixed |
perf | Changed |
refactor | Changed |
test | (skip) |
If a commit has ! (breaking change), also note it under Changed with a clear migration note.
Each entry should be:
(see [#N]) at the end when an issue exists, where [#N] is a
reference-style link to the GitHub issue.by @username
before any issue reference. Omit attribution for commits by the repository owner.Good:
- `--back` flag on `finish` command to backdate `@done` timestamp using natural language by @contributor (see [#42])
- Timezone detection now respects `TZ` environment variable (see [#58])
Bad:
- Added backdate support to finish command (implements feature from issue #42)
- fix(cli): resolve flag parsing edge case in finish --back handler
Read the current CHANGELOG.md. Replace only the ## [Unreleased] section content (between the
## [Unreleased] heading and the next ## heading). Preserve all other sections and reference links.
The Unreleased section should contain only the categories that have entries (omit empty categories). Order categories: Added, Changed, Deprecated, Removed, Fixed, Security.
Ensure all [#N] issue references have corresponding reference-style links at the bottom of the file.
Reference links are numerically sorted. The [Unreleased] comparison link should compare the latest
tag to main.
Show the user the updated Unreleased section and ask for approval before writing the file.