by @tilomitra
Generate or update CHANGELOG.md entries from git history, PRs, and issues using Keep a Changelog format. Triggered by requests to update changelogs, document changes, or summarize what changed between versions.
Generate CHANGELOG.md entries by analyzing code changes, PRs, and issues — not just commit messages.
When asked to generate a changelog entry (e.g., for a version or tag range), collect context from multiple sources. Commit messages are often vague or useless, so prioritize richer signals.
# Get the two most recent tags
CURRENT_TAG=$(git describe --tags --abbrev=0)
PREVIOUS_TAG=$(git describe --tags --abbrev=0 "$CURRENT_TAG^")
# Or if the user specifies a version:
# CURRENT_TAG="v2.4.0"
# PREVIOUS_TAG=$(git describe --tags --abbrev=0 "$CURRENT_TAG^")
# Get the date of the previous tag for filtering PRs/issues
SINCE_DATE=$(git log -1 --format=%aI "$PREVIOUS_TAG")
PRs merged since last release:
gh pr list --state merged --search "merged:>=$SINCE_DATE" --json number,title,body,labels --limit 100
Issues closed since last release:
gh issue list --state closed --search "closed:>=$SINCE_DATE" --json number,title,body,labels --limit 100
Diff between tags:
git diff "$PREVIOUS_TAG".."$CURRENT_TAG" -- '*.ts' '*.js' '*.tsx' '*.jsx' '*.py' '*.go' '*.rs' ':!*.lock' ':!*.min.*'
Files changed:
git diff --name-only "$PREVIOUS_TAG".."$CURRENT_TAG"
New or changed test descriptions (reveal intent):
git diff "$PREVIOUS_TAG".."$CURRENT_TAG" -- '**/*.test.*' '**/*.spec.*' '**/test_*' '**/*_test.*'
Config and dependency changes:
git diff "$PREVIOUS_TAG".."$CURRENT_TAG" -- 'package.json' '*.toml' '*.yaml' '*.yml' '*.env.example' '*.config.*'
Commit messages (last resort):
git log --oneline "$PREVIOUS_TAG".."$CURRENT_TAG"
Classify every change into one of these Keep a Changelog categories: