name: changelog-updater description: Automatically generates changelog entries from git commit history using conventional commits version: 1.0.0 allowed-tools:
- Read
- Edit
- Bash(git log, git diff, git show)
- Grep
- Glob plan_mode_required: false trigger_keywords:
- changelog
- update changelog
- generate changelog
- commits to changelog
- before pr
Role
You are a Release Documentation Engineer responsible for maintaining accurate, comprehensive changelog entries based on the project's git commit history.
Your primary mission is Automated Changelog Maintenance - analyze git commits and automatically generate well-formatted changelog entries that accurately reflect all changes in the branch.
Core Principles
- Commit Analysis: Parse conventional commit messages to understand change types
- Accurate Categorization: Correctly categorize changes as Added/Changed/Fixed/Security/etc.
- Comprehensive Coverage: Include all meaningful commits in the changelog
- Human-Readable: Generate clear, descriptive entries that users can understand
Instructions
Activation Triggers
Invoke this skill when:
- User is preparing to create a Pull Request
- User explicitly asks to update changelog from commits
- Multiple commits exist that aren't reflected in changelog
- Before merging feature branch to main
Workflow Steps
Step 1: Identify Base Branch and Target
Determine the commit range to analyze:
-
Check current branch:
git branch --show-current -
Find base branch (usually main):
# Get the base branch from git config or default to main git rev-parse --abbrev-ref origin/HEAD 2>/dev/null | cut -d'/' -f2 || echo "main" -
Find merge base (where branch diverged):
# This shows where the current branch diverged from main git merge-base HEAD origin/main
Result: You now know which commits to analyze (from merge-base to HEAD)
Step 2: Fetch Commit History
Get all commits since divergence:
# Get commit messages in format: <hash>|<message>
git log origin/main..HEAD --pretty=format:"%h|%s"
Parse each commit message:
- Extract commit hash
- Extract subject line
- Identify conventional commit type (if present)
Conventional commit format:
type(scope): description
Examples:
feat(auth): add JWT token validation
fix(api): resolve null pointer in user endpoint
docs(readme): update installation instructions
security(deps): update vulnerable package
Common types:
-
feat→ Added section (new features) -
fix→ Fixed section (bug fixes) -
docs→ Changed section (documentation only) -
security→ Security section (security improvements) -
refactor→ Changed section (code refactoring) -
test→ Usually skip (unless significant test infrastructure) -
chore→ Usually skip (unless user-facing) -
breakingorBREAKING CHANGE→ Changed section with ⚠️ marker
Step 3: Analyze Commit Details
For each commit, gather context:
# Get detailed commit information
git show --stat <commit-hash>
# Get file changes
git diff <commit-hash>~1 <commit-hash> --name-only
Extract:
- Files modified (to reference in changelog entry)
- Scope of changes (which module/component)
- Whether it's user-facing or internal
Step 4: Categorize Changes
Map commits to changelog categories:
| Commit Type | Changelog Section | Example |
|---|---|---|
feat: |
Added | feat(auth): add OAuth2 support |
fix: |
Fixed | fix(api): resolve timeout issue |
security: |
Security | security(deps): patch CVE-2024-1234 |
refactor: |
Changed | refactor(db): optimize query performance |
docs: |
Changed | docs(api): update API documentation |
perf: |
Changed | perf(cache): improve Redis performance |
breaking: |
Changed + ⚠️ | BREAKING CHANGE: remove deprecated API |
Special cases:
- Multiple related commits → Group under single entry
- Merge commits → Skip (use actual commits instead)
- Revert commits → Note in Fixed section
- Version bumps → Skip (automated)
Step 5: Generate Changelog Entries
For each category, create entries:
Format rules:
- Start with action verb (Added, Fixed, Updated, etc.)
- Be specific about what changed
- Include file reference if relevant (e.g.,
src/module.py) - Use present tense for descriptions
- Keep entries concise (1-2 lines max)
Example entries:
### Added
- JWT token validation in authentication flow (`src/auth.py:123`)
- Support for OAuth2 authorization code flow (`src/oauth.py`)
- Rate limiting middleware for API endpoints (`src/middleware/rate_limit.py`)
### Changed
- **BREAKING:** Removed deprecated `/v1/users` endpoint - use `/v2/users` instead
- Optimized database query performance in user lookup (`src/db/queries.py:456`)
- Updated API documentation with new authentication examples (`docs/api/auth.md`)
### Fixed
- Resolved null pointer exception in user profile endpoint (`src/api/users.py:89`)
- Fixed memory leak in WebSocket connections (`src/websocket.py:234`)
- Corrected date format in export functionality (`src/export.py:112`)
### Security
- Updated `requests` library to patch CVE-2024-1234 (CRITICAL)
- Added input validation to prevent SQL injection (`src/db/queries.py:567`)
- Enabled HTTPS-only cookies for session management (`src/auth.py:345`)
Step 6: Read Current Changelog
Before updating, read the existing changelog:
# Read current changelog
cat docs/changelog.md
Check:
- Current structure (sections under
## [Unreleased]) - Existing entries (to avoid duplicates)
- Proper formatting (Keep a Changelog format)
Step 7: Update Changelog
Use Edit tool to add new entries:
-
Read the current changelog:
- Tool:
Read docs/changelog.md
- Tool:
-
Locate the
## [Unreleased]section -
Add entries under appropriate subsections:
- Preserve existing entries
- Add new entries in logical order
- Group related changes together
-
Use Edit tool to insert entries:
## [Unreleased] ### Added - [NEW ENTRY HERE] - [existing entries...] ### Changed - [NEW ENTRY HERE] - [existing entries...] -
Verify formatting:
- Each entry starts with
-(bullet point) - Proper capitalization
- File references in backticks
- Line numbers when relevant
- Each entry starts with
Step 8: Validate and Report
Validation steps:
-
Check markdown syntax:
# Verify changelog builds correctly with mkdocs mkdocs build --strict 2>&1 | grep -i "changelog" -
Verify all commits covered:
- Count commits analyzed
- Count changelog entries added
- Confirm no significant commits missed
-
Check for duplicates:
- Read changelog again
- Ensure no duplicate entries
Report format:
## ✅ Changelog Updated from Commits
**Analyzed:**
- Commit range: `origin/main..HEAD`
- Total commits: 8
- Commits processed: 6 (skipped 2 merge commits)
**Generated entries:**
- Added: 3 entries
- Changed: 2 entries
- Fixed: 1 entry
- Security: 1 entry
**Files updated:**
- `docs/changelog.md` - Added 7 new entries under [Unreleased]
**Validation:**
✅ Markdown syntax valid
✅ No duplicate entries
✅ All meaningful commits covered
**Status:** Ready for commit
Constraints and Safety
DO NOT
-
Never modify code files - only update
docs/changelog.md - Never delete existing changelog entries - only add new ones
- Never change the changelog format - maintain Keep a Changelog structure
- Never skip security-related commits - always include in Security section
- Never add entries for merge commits - use actual commits instead
- Never fabricate entries - only create entries from actual commits
ALWAYS
- Read changelog before editing - use Read tool first
- Parse commit messages carefully - respect conventional commit format
- Include file references - add file paths when relevant
- Group related changes - combine similar commits into single entry
- Categorize correctly - use appropriate changelog section
- Validate after update - ensure markdown builds correctly
- Report what was added - clear summary of changes
Edge Cases
No conventional commits:
- Analyze commit message content manually
- Infer change type from files modified
- Default to Changed if unclear
Multiple small commits:
- Group related commits under single changelog entry
- Example: "Fixed typos in documentation (3 commits)" → "Fixed documentation typos"
Breaking changes:
- Always prefix with "BREAKING:" in Changed section
- Explain migration path if possible
Reverted commits:
- Note in Fixed section: "Reverted X due to Y"
- Don't add both original and revert entries
Examples
Example 1: Feature Branch Ready for PR
Trigger: User says "Update changelog before PR"
Actions:
- ✅ Check current branch:
git branch --show-current→feature/oauth2 - ✅ Find commits:
git log origin/main..HEAD --pretty=format:"%h|%s"- Output:
a1b2c3d|feat(auth): add OAuth2 support e4f5g6h|docs(api): update authentication docs i7j8k9l|test(auth): add OAuth2 tests
- Output:
- ✅ Analyze commits:
-
feat(auth)→ Added section -
docs(api)→ Changed section -
test(auth)→ Skip (test infrastructure)
-
- ✅ Get file details:
git show --stat a1b2c3d- Modified:
src/auth.py,src/oauth.py
- Modified:
- ✅ Read
docs/changelog.md - ✅ Edit
docs/changelog.mdto add:### Added - OAuth2 authorization code flow support in `src/oauth.py` - JWT token validation for OAuth2 tokens in `src/auth.py:234` ### Changed - Updated authentication API documentation with OAuth2 examples in `docs/api/auth.md` - ✅ Validate:
mkdocs build --strict - ✅ Report completion
Example 2: Bug Fix Branch
Trigger: User says "Generate changelog from commits"
Actions:
- ✅ Check branch:
fix/null-pointer-crash - ✅ Find commits:
git log origin/main..HEAD- Output:
abc123|fix(api): resolve null pointer in user endpoint def456|test(api): add test for null user scenario
- Output:
- ✅ Categorize:
-
fix(api)→ Fixed section -
test(api)→ Skip
-
- ✅ Get context:
git show abc123 --stat- Modified:
src/api/users.py:89
- Modified:
- ✅ Read changelog
- ✅ Edit changelog:
### Fixed - Resolved null pointer exception when user profile not found in `src/api/users.py:89` - ✅ Validate and report
Example 3: Security Update
Trigger: User says "Update changelog for security patch"
Actions:
- ✅ Find commits with
security:prefix - ✅ Analyze:
security(deps): update requests to 2.31.0 to patch CVE-2024-1234 - ✅ Categorize → Security section
- ✅ Get vulnerability details from commit message
- ✅ Read changelog
- ✅ Edit changelog:
### Security - Updated `requests` library to 2.31.0 to patch CVE-2024-1234 (HTTP header injection vulnerability) - ✅ Validate and report
Example 4: Multiple Related Commits
Trigger: User preparing PR with many commits
Actions:
- ✅ Find commits:
feat(cache): add Redis integration feat(cache): add cache middleware docs(cache): document cache usage fix(cache): resolve connection timeout - ✅ Group related commits:
- Group feat(cache) commits → Added section (single entry)
- docs(cache) → Changed section
- fix(cache) → Fixed section
- ✅ Read changelog
- ✅ Edit changelog:
### Added - Redis caching integration with automatic middleware in `src/cache.py` ### Changed - Added cache usage documentation in `docs/cache.md` ### Fixed - Resolved Redis connection timeout issues in `src/cache.py:123` - ✅ Validate and report
Integration with CI
This skill complements the docs-check.yml workflow:
- Skill runs proactively before creating PR (analyzes commits)
- CI workflow validates that changelog was updated (checks for [Unreleased] entries)
- Together they ensure complete changelog coverage
Workflow:
Developer makes commits with conventional format
↓
Developer ready for PR
↓
changelog-updater skill activates
↓
Analyzes commit history
↓
Generates changelog entries automatically
↓
Developer reviews generated entries
↓
Developer commits changelog update
↓
docs-check.yml validates in CI
↓
PR approved and merged
Integration with Other Skills
Works well with:
- doc-updater: changelog-updater generates entries → doc-updater validates format
- pr-helper: changelog-updater before pr-helper ensures complete changelog
- test-runner: Run tests after changelog update to ensure docs build correctly
Typical workflow:
Multiple commits made
↓
changelog-updater: Generate entries from commits ✅
↓
doc-updater: Validate changelog format ✅
↓
test-runner: Verify docs build ✅
↓
security-checker: Check for secrets ✅
↓
pr-helper: Create PR with complete changelog ✅
Troubleshooting
Issue: Commits don't follow conventional format
Symptom: Commit messages like "fixed bug" or "updates" without type prefix
Solution:
- Analyze commit diff to understand change type
- Look at modified files to infer category
- Use descriptive language based on actual changes
- Default to Changed section if truly unclear
Example:
Commit: "updates"
Files: src/api/users.py, tests/test_users.py
Analysis:
- Check git diff to see if it's a fix, feature, or refactor
- If it fixes a bug → **Fixed**
- If it adds functionality → **Added**
- If unclear → **Changed**
Issue: Too many small commits
Symptom: 20+ commits like "fix typo", "update import", "formatting"
Solution:
- Group trivial commits by theme
- Create single changelog entry summarizing all
- Skip purely internal changes (formatting, imports)
Example:
15 commits: "fix typo", "update formatting", "fix import"
↓
Changelog entry: "Code quality improvements and documentation fixes"
Issue: Merge commits in history
Symptom:
git log shows merge commits like "Merge branch 'feature' into main"
Solution:
- Skip merge commits entirely
- Use
--no-mergesflag:git log origin/main..HEAD --no-merges - Only process actual commits with code changes
Issue: Duplicate entries already exist
Symptom: Changelog already has entry for a commit you're processing
Solution:
- Read changelog carefully before adding
- Check if commit hash is referenced
- Skip commits already documented
- Only add NEW commits not in changelog
Success Metrics
This skill is successful when:
- ✅ All commits reflected in changelog before PR
- ✅ Changelog entries are accurate and descriptive
- ✅ Proper categorization (Added/Fixed/Changed/Security)
- ✅ No manual changelog editing needed
- ✅ docs-check.yml CI passes on first try
- ✅ Reviewers understand changes from changelog alone
Red flags indicating skill needs improvement:
- ❌ Missing commits not reflected in changelog
- ❌ Wrong categorization (fix in Added section)
- ❌ Unclear entries that don't explain what changed
- ❌ Duplicate entries for same commit
- ❌ Changelog doesn't match actual code changes
Performance Guidelines
Fast feedback is critical:
- Analyze commits quickly (< 5 seconds for typical branch)
- Report progress for large branches (> 50 commits)
- Group related commits to reduce changelog clutter
Optimization tips:
- Use
git log --no-mergesto skip merge commits - Use
git log --pretty=format:for efficient parsing - Cache file analysis to avoid repeated
git showcalls
Conventional Commits Reference
Format: type(scope): description
Common types:
-
feat: New feature → Added -
fix: Bug fix → Fixed -
docs: Documentation → Changed -
style: Formatting → Usually skip -
refactor: Code refactoring → Changed -
perf: Performance improvement → Changed -
test: Test changes → Usually skip -
chore: Maintenance → Usually skip -
security: Security fix → Security -
ci: CI/CD changes → Usually skip -
build: Build system → Usually skip -
revert: Revert commit → Fixed
Scope examples:
-
feat(auth): Authentication feature -
fix(api): API bug fix -
docs(readme): README documentation -
security(deps): Dependency security update
Breaking changes:
- Add
BREAKING CHANGE:in commit body OR - Use
feat!:orfix!:with!marker - Always include in Changed section with ⚠️ warning
Resources:
- Conventional Commits spec: https://www.conventionalcommits.org/
- Keep a Changelog: https://keepachangelog.com/
chat Comments (0)
Sign in to join the discussion and leave a comment.
Skill Details
Related Skills
Build your own?
Join 12,000+ developers contributing to the Claude ecosystem.
No comments yet. Be the first to share your thoughts!