# Changelog Gen

> Build a CHANGELOG.md from conventional commits. Groups by type (feat, fix, perf...) and infers semver bump.

- Skill: `kasimmj/changelog-gen` (Agent Skill)
- Install (CLI): `npx skillmds@latest add kasimmj/changelog-gen`
- Raw SKILL.md: https://api.skillmd.com/api/skills/kasimmj/changelog-gen/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: kasimmj (https://skillmd.com/u/kasimmj)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/kasimmj/changelog-gen

---


# Changelog Generation Skill

You are generating a **CHANGELOG entry** from git history.

## Step 1 — Pick the range

Ask (or infer):
- Since the last tag: `git log $(git describe --tags --abbrev=0)..HEAD`
- Since a specific tag: `git log v1.2.0..HEAD`
- All time: full history (rare; only for first release)

If `git describe` fails (no tags), this is the first release — say so.

## Step 2 — Parse conventional commits

Recognized prefixes:
- `feat:` / `feat(scope):` → **Features**
- `fix:` / `fix(scope):` → **Bug Fixes**
- `perf:` → **Performance**
- `refactor:` → **Refactors**
- `docs:` → **Documentation**
- `test:` → **Tests**
- `build:` / `ci:` → **Build & CI**
- `chore:` → **Chore** (often omitted from changelog)
- `revert:` → **Reverts**

Breaking changes:
- Footer `BREAKING CHANGE:` or `!` after type (e.g., `feat!:`)
- These get a 🚨 prefix and forces a major bump

## Step 3 — Infer semver bump

| Commits found | Bump |
|---------------|------|
| Any BREAKING CHANGE | `MAJOR` |
| Any `feat:` (no breaking) | `MINOR` |
| Only `fix:`, `perf:`, `refactor:`, `docs:`, etc. | `PATCH` |
| Only `docs:`, `chore:`, `test:` | No release recommended |

## Step 4 — Write the CHANGELOG

Format:

```markdown
## [1.4.0] — 2026-05-22

### 🚀 Features
- **auth**: support OAuth via GitHub (#142)
- **dashboard**: add export-to-CSV button (#138)

### 🐛 Bug Fixes
- **api**: handle 429 from upstream gracefully (#145)

### ⚡ Performance
- **db**: index `users.email` (#147) — login query 12× faster

### 🚨 Breaking Changes
- **config**: rename `API_KEY` → `OPENAI_API_KEY` (#150)
  Migration: rename your env var. See UPGRADE.md.
```

Each entry:
- Includes the scope if present
- Links the PR or commit hash
- Strips the conventional prefix (no `feat:` in the bullet itself)
- Has a one-line description — full PR title

## Step 5 — Update CHANGELOG.md

If a `CHANGELOG.md` exists, prepend the new section above the most recent release.
If not, create one with a "Keep a Changelog" header.

## Step 6 — Suggest next steps

Print:
- New version: `<computed>`
- Suggested tag: `git tag -a vX.Y.Z -m "Release vX.Y.Z"`
- If `package.json` exists: `npm version <bump> --no-git-tag-version`

## When NOT to use

- Commits don't follow conventional commits — recommend `cz-commitlint` setup first
- The user wants release notes in a totally different format (e.g., for marketing)

## Failure modes

- ⚠️ Squash-merged PRs may lose individual commit messages. The PR title becomes the commit. That's usually fine.
- ⚠️ If a commit message is just `fix: stuff`, flag it — recommend amending.

