Generate or update a repository CHANGELOG.md in Keep a Changelog format from git history - grouping commits since the last tag into Added/Changed/Deprecated/Removed/Fixed/Security, rewriting them as user-facing entries, and recommending the semantic version bump. Use when someone asks "generate a changelog from the git log", "update CHANGELOG.md for this release", "what version bump does this release need", or "turn these commits into release notes". Do NOT use for writing benefit-first product announcement changelogs for end users from release notes - use changelog-writer instead; this skill produces the versioned CHANGELOG.md file that lives in the repo.
Click to play with sound.
---
name: Changelog Generator
description: Generate or update a repository CHANGELOG.md in Keep a Changelog format from git history - grouping commits since the last tag into Added/Changed/Deprecated/Removed/Fixed/Security, rewriting them as user-facing entries, and recommending the semantic version bump. Use when someone asks "generate a changelog from the git log", "update CHANGELOG.md for this release", "what version bump does this release need", or "turn these commits into release notes". Do NOT use for writing benefit-first product announcement changelogs for end users from release notes - use changelog-writer instead; this skill produces the versioned CHANGELOG.md file that lives in the repo.
---
# Changelog Generator
A changelog exists so a human deciding whether to upgrade can answer "what breaks, what's fixed, what's new" in thirty seconds. The costly failure is dumping `git log` into a file: raw commit messages describe the code's history, not the release's meaning, and they bury the one breaking change under forty chores. This skill turns commit history into a Keep a Changelog-formatted CHANGELOG.md and a defensible version bump.
## Inputs to collect
Gather before writing: the repo (or the raw log), the last released tag (`git describe --tags --abbrev=0` - if there are no tags, the whole history is the first release), the existing CHANGELOG.md if any (append to its conventions rather than reformatting history), whether commits follow Conventional Commits (`feat:`, `fix:` prefixes make categorization mechanical; otherwise categorize by reading each diff's intent), and the project's versioning scheme (default: SemVer). Label any inferred categorization from an ambiguous commit as a guess for the maintainer to confirm.
## Operating procedure
Order matters: categorize before writing, and decide the version last, because the bump is a function of the finished category lists.
1. **Collect the range.** `git log <last-tag>..HEAD --oneline --no-merges`. Pull PR numbers from merge commits or squash-commit suffixes like `(#123)`.
2. **Drop invisible commits.** Remove chores, CI tweaks, test-only changes, dependency bumps, refactors, and formatting - unless one produced a user-visible result, in which case describe the result, not the work ("Reduced install size by 40%", not "Switched bundler").
3. **Categorize every surviving commit** into exactly one Keep a Changelog category:
- **Added** - new features and capabilities (`feat:`).
- **Changed** - existing behavior that now works differently.
- **Deprecated** - still works, will be removed; say what to use instead.
- **Removed** - gone; this is breaking.
- **Fixed** - bug fixes (`fix:`), described by the symptom the user saw.