---
name: changelog-generator
description: "Build CHANGELOG.md from git history — Keep-a-Changelog format, grouped by Added/Changed/Fixed/Removed. Walks git history from the last release tag, groups commits by Conventional Commits type, drops noise (chore, ci, deps), and writes a CHANGELOG.md section in Keep-a-Changelog format with user-facing wording."
license: MIT
---

# Changelog Generator

Turn raw git history into a clean `CHANGELOG.md` entry that follows the [Keep a Changelog](https://keepachangelog.com) convention. The skill reads commits since your last release tag, sorts them by Conventional Commits type, strips out internal noise, and rewrites the messages into user-facing language grouped under **Added**, **Changed**, **Fixed**, and **Removed**. It's built for maintainers who tag releases and would rather review a draft than hand-assemble release notes line by line.

## When to use it

- You're cutting a release (`v1.4.0`) and need the changelog section before you tag.
- Your commit log is full of `feat:`/`fix:` messages and you want them translated for readers who don't live in the repo.
- You inherited a project with no changelog and want to backfill one release at a time.
- You want a consistent format across repos so release tooling and humans can both parse it.

## How it works

1. Finds the most recent tag with `git describe --tags --abbrev=0` and collects commits with `git log <lasttag>..HEAD`. If no tag exists, it walks the full history.
2. Parses each subject line as a Conventional Commit (`type(scope): description`), reading the type prefix to bucket it.
3. Maps types to sections: `feat` → Added, `fix` → Fixed, `refactor`/`perf`/`style` → Changed, and removals (often flagged via `BREAKING CHANGE:` footers or `revert`) → Removed.
4. Drops `chore`, `ci`, `build`, `test`, `docs`, and dependency bumps (`deps`) so the entry stays reader-focused.
5. Rewrites terse subjects into plain past-tense sentences and writes a dated `## [version] - YYYY-MM-DD` block at the top of `CHANGELOG.md`, preserving everything already in the file.

## Usage

```
curl -fsSL --create-dirs -o ~/.claude/skills/changelog-generator/SKILL.md https://claudeskil.com/skills/changelog-generator/SKILL.md

# In your repo, with the new version you're about to release:
> Generate a changelog entry for v2.1.0

# It runs roughly:
git describe --tags --abbrev=0        # -> v2.0.0
git log v2.0.0..HEAD --pretty=%s
# then prepends to CHANGELOG.md:
```

```markdown
## [2.1.0] - 2026-06-30
### Added
- CSV export on the reports page
### Fixed
- Session timeout no longer logs users out mid-form
```

## Tips & gotchas

- **Tags drive the diff.** If your last release was never tagged, point the skill at a base ref explicitly, or it will dump the entire history into one section.
- **Breaking changes need the footer.** A `feat!:` or `BREAKING CHANGE:` line is what surfaces it prominently; a plain `feat:` reads as a normal addition.
- **Squash vs. merge matters.** Squash-merge workflows give one clean Conventional subject per PR; merge commits can scatter noise the parser then has to skip.
- Always read the draft before committing — generated wording is a starting point, not gospel, especially for security-sensitive fixes.

## FAQ

**Does it bump the version or create the git tag?** No. It only writes the changelog section. You stay in control of `npm version`/tagging.

**What if my commits don't follow Conventional Commits?** Unprefixed commits land in a best-effort bucket (usually Changed). The cleaner your prefixes, the cleaner the grouping.

**Can it regenerate notes for an older release?** Yes — give it the two surrounding tags (e.g. `v1.2.0..v1.3.0`) and it builds that historical section.
