
Changelog Automation
- 10.9k installs
- 38.3k repo stars
- Updated July 22, 2026
- wshobson/agents
How to automate changelog generation from git commits, PRs, and releases using Conventional Commits and Keep a Changelog standards.
About
This skill teaches patterns and tools for automating changelog generation, release notes, and version management following industry standards like Keep a Changelog and Conventional Commits. Developers use it when setting up release workflows, implementing commit message standards, and generating GitHub/GitLab release notes. Key workflows include writing scoped commit messages (e.g. feat(auth), fix(checkout)), marking breaking changes with `!` or footer, referencing issues in commits, and validating commits via commitlint in CI pipelines. The skill covers semantic versioning integration, structured release note templates with highlights and upgrade guides, and best practices like one logical change per commit and never manually editing generated changelogs.
- Keep a Changelog format with sections for features, fixes, breaking changes, and upgrade guides
- Conventional Commits syntax (feat, fix, type!) enables automated changelog generation from git history
- Commit validation via commitlint in CI pipelines prevents non-standard messages
- Semantic versioning alignment for automated version bumping based on change types
- Scoped commit messages (auth, checkout, api) organize changes by functional area
Changelog Automation by the numbers
- 10,904 all-time installs (skills.sh)
- +229 installs in the week ending Jul 28, 2026 (Skillselion tracking)
- Ranked #1 of 257 Release Management skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Jul 28, 2026 (Skillselion catalog sync)
changelog-automation capabilities & compatibility
- Capabilities
- parse git commit history into structured changel · validate commits against conventional commits sp · generate release notes with highlights and break · automate semantic version bumping · integrate with ci/cd pipelines
- Works with
- github · gitlab · bitbucket
- Use cases
- documentation · ci cd · code review
- Platforms
- macOS · Windows · Linux
- Runs
- Runs locally
- Pricing
- Free
What changelog-automation says it does
feat(auth): add OAuth2 support for Google login
npx skills add https://github.com/wshobson/agents --skill changelog-automationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 10.9k |
|---|---|
| repo stars | ★ 38.3k |
| Security audit | 2 / 3 scanners passed |
| Last updated | July 22, 2026 |
| Repository | wshobson/agents ↗ |
What it does
Automate changelog and release notes generation from commits and PRs using Conventional Commits and Keep a Changelog format.
Who is it for?
Teams implementing release workflows, standardizing commit conventions, automating release notes, managing semantic versioning at scale.
Skip if: Single-file scripts, projects with no formal release process, teams not ready to adopt commit message standards.
When should I use this skill?
Setting up CI/CD release automation, establishing commit message conventions, creating release note templates, integrating with GitHub/GitLab.
What you get
Developers can generate standardized, complete changelogs automatically from structured commits, reducing manual work and improving release note quality.
- Standardized commit message format
- Automated changelog generation workflow
- Release note templates
By the numbers
- Keep a Changelog format includes 8 standard sections: Unreleased, versions with added/changed/deprecated/removed/fixed/s
- Conventional Commits types covered: feat, fix, with optional scope and breaking change marker
Files
Changelog Automation
Patterns and tools for automating changelog generation, release notes, and version management following industry standards.
When to Use This Skill
- Setting up automated changelog generation
- Implementing Conventional Commits
- Creating release note workflows
- Standardizing commit message formats
- Generating GitHub/GitLab release notes
- Managing semantic versioning
Core Concepts
1. Keep a Changelog Format
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Detailed patterns and worked examples
Detailed pattern documentation lives in `references/details.md`. Read that file when the navigation tier above is insufficient.
## Summary
This release introduces dark mode support and improves checkout performance
by 40%. It also includes important security updates.
## Highlights
### 🌙 Dark Mode
Users can now switch to dark mode from settings. The preference is
automatically saved and synced across devices.
### ⚡ Performance
- Checkout flow is 40% faster
- Reduced bundle size by 15%
## Breaking Changes
None in this release.
## Upgrade Guide
No special steps required. Standard deployment process applies.
## Known Issues
- Dark mode may flicker on initial load (fix scheduled for v2.1.1)
## Dependencies Updated
| Package | From | To | Reason |
| ------- | ------- | ------- | ------------------------ |
| react | 18.2.0 | 18.3.0 | Performance improvements |
| lodash | 4.17.20 | 4.17.21 | Security patch |Commit Message Examples
# Feature with scope
feat(auth): add OAuth2 support for Google login
# Bug fix with issue reference
fix(checkout): resolve race condition in payment processing
Closes #123
# Breaking change
feat(api)!: change user endpoint response format
BREAKING CHANGE: The user endpoint now returns `userId` instead of `id`.
Migration guide: Update all API consumers to use the new field name.
# Multiple paragraphs
fix(database): handle connection timeouts gracefully
Previously, connection timeouts would cause the entire request to fail
without retry. This change implements exponential backoff with up to
3 retries before failing.
The timeout threshold has been increased from 5s to 10s based on p99
latency analysis.
Fixes #456
Reviewed-by: @aliceBest Practices
Do's
- Follow Conventional Commits - Enables automation
- Write clear messages - Future you will thank you
- Reference issues - Link commits to tickets
- Use scopes consistently - Define team conventions
- Automate releases - Reduce manual errors
Don'ts
- Don't mix changes - One logical change per commit
- Don't skip validation - Use commitlint
- Don't manual edit - Generated changelogs only
- Don't forget breaking changes - Mark with
!or footer - Don't ignore CI - Validate commits in pipeline
changelog-automation — detailed patterns and worked examples
[Unreleased]
Added
- New feature X
[1.2.0] - 2024-01-15
Added
- User profile avatars
- Dark mode support
Changed
- Improved loading performance by 40%
Deprecated
- Old authentication API (use v2)
Removed
- Legacy payment gateway
Fixed
- Login timeout issue (#123)
Security
- Updated dependencies for CVE-2024-1234
[Unreleased]: https://github.com/user/repo/compare/v1.2.0...HEAD [1.2.0]: https://github.com/user/repo/compare/v1.1.0...v1.2.0
### 2. Conventional Commits
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
| Type | Description | Changelog Section |
| ---------- | ---------------- | ------------------ |
| `feat` | New feature | Added |
| `fix` | Bug fix | Fixed |
| `docs` | Documentation | (usually excluded) |
| `style` | Formatting | (usually excluded) |
| `refactor` | Code restructure | Changed |
| `perf` | Performance | Changed |
| `test` | Tests | (usually excluded) |
| `chore` | Maintenance | (usually excluded) |
| `ci` | CI changes | (usually excluded) |
| `build` | Build system | (usually excluded) |
| `revert` | Revert commit | Removed |
### 3. Semantic Versioning
MAJOR.MINOR.PATCH
MAJOR: Breaking changes (feat! or BREAKING CHANGE) MINOR: New features (feat) PATCH: Bug fixes (fix)
## Implementation
### Method 1: Conventional Changelog (Node.js)
Install tools
npm install -D @commitlint/cli @commitlint/config-conventional npm install -D husky npm install -D standard-version
or
npm install -D semantic-release
Setup commitlint
cat > commitlint.config.js << 'EOF' module.exports = { extends: ['@commitlint/config-conventional'], rules: { 'type-enum': [ 2, 'always', [ 'feat', 'fix', 'docs', 'style', 'refactor', 'perf', 'test', 'chore', 'ci', 'build', 'revert', ], ], 'subject-case': [2, 'never', ['start-case', 'pascal-case', 'upper-case']], 'subject-max-length': [2, 'always', 72], }, }; EOF
Setup husky
npx husky init echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg
### Method 2: standard-version Configuration
// .versionrc.js module.exports = { types: [ { type: "feat", section: "Features" }, { type: "fix", section: "Bug Fixes" }, { type: "perf", section: "Performance Improvements" }, { type: "revert", section: "Reverts" }, { type: "docs", section: "Documentation", hidden: true }, { type: "style", section: "Styles", hidden: true }, { type: "chore", section: "Miscellaneous", hidden: true }, { type: "refactor", section: "Code Refactoring", hidden: true }, { type: "test", section: "Tests", hidden: true }, { type: "build", section: "Build System", hidden: true }, { type: "ci", section: "CI/CD", hidden: true }, ], commitUrlFormat: "{{host}}/{{owner}}/{{repository}}/commit/{{hash}}", compareUrlFormat: "{{host}}/{{owner}}/{{repository}}/compare/{{previousTag}}...{{currentTag}}", issueUrlFormat: "{{host}}/{{owner}}/{{repository}}/issues/{{id}}", userUrlFormat: "{{host}}/{{user}}", releaseCommitMessageFormat: "chore(release): {{currentTag}}", scripts: { prebump: 'echo "Running prebump"', postbump: 'echo "Running postbump"', prechangelog: 'echo "Running prechangelog"', postchangelog: 'echo "Running postchangelog"', }, };
// package.json scripts { "scripts": { "release": "standard-version", "release:minor": "standard-version --release-as minor", "release:major": "standard-version --release-as major", "release:patch": "standard-version --release-as patch", "release:dry": "standard-version --dry-run" } }
### Method 3: semantic-release (Full Automation)
// release.config.js module.exports = { branches: [ "main", { name: "beta", prerelease: true }, { name: "alpha", prerelease: true }, ], plugins: [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", [ "@semantic-release/changelog", { changelogFile: "CHANGELOG.md", }, ], [ "@semantic-release/npm", { npmPublish: true, }, ], [ "@semantic-release/github", { assets: ["dist/*/.js", "dist/*/.css"], }, ], [ "@semantic-release/git", { assets: ["CHANGELOG.md", "package.json"], message: "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}", }, ], ], };
### Method 4: GitHub Actions Workflow
.github/workflows/release.yml
name: Release
on: push: branches: [main] workflow_dispatch: inputs: release_type: description: "Release type" required: true default: "patch" type: choice options:
- patch
- minor
- major
permissions: contents: write pull-requests: write
jobs: release: runs-on: ubuntu-latest steps:
- uses: actions/checkout@v4
with: fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/setup-node@v4
with: node-version: "20" cache: "npm"
- run: npm ci
- name: Configure Git
run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Run semantic-release
env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: npx semantic-release
Alternative: manual release with standard-version
manual-release: if: github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest steps:
- uses: actions/checkout@v4
with: fetch-depth: 0
- uses: actions/setup-node@v4
with: node-version: "20"
- run: npm ci
- name: Configure Git
run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Bump version and generate changelog
run: npx standard-version --release-as ${{ inputs.release_type }}
- name: Push changes
run: git push --follow-tags origin main
- name: Create GitHub Release
uses: softprops/action-gh-release@v1 with: tag_name: ${{ steps.version.outputs.tag }} body_path: RELEASE_NOTES.md generate_release_notes: true
### Method 5: git-cliff (Rust-based, Fast)
cliff.toml
[changelog] header = """
Changelog
All notable changes to this project will be documented in this file.
""" body = """ {% if version %}\
[{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
{% else %}\
[Unreleased]
{% endif %}\ {% for group, commits in commits | group_by(attribute="group") %}
{{ group | upper_first }}
{% for commit in commits %}
- {% if commit.scope %}{{ commit.scope }}: {% endif %}\
{{ commit.message | upper_first }}\ {% if commit.github.pr_number %} ([#{{ commit.github.pr_number }}](https://github.com/owner/repo/pull/{{ commit.github.pr_number }})){% endif %}\ {% endfor %} {% endfor %} """ footer = """ {% for release in releases -%} {% if release.version -%} {% if release.previous.version -%} [{{ release.version | trim_start_matches(pat="v") }}]: \ https://github.com/owner/repo/compare/{{ release.previous.version }}...{{ release.version }} {% endif -%} {% else -%} [unreleased]: https://github.com/owner/repo/compare/{{ release.previous.version }}...HEAD {% endif -%} {% endfor %} """ trim = true
[git] conventional_commits = true filter_unconventional = true split_commits = false commit_parsers = [ { message = "^feat", group = "Features" }, { message = "^fix", group = "Bug Fixes" }, { message = "^doc", group = "Documentation" }, { message = "^perf", group = "Performance" }, { message = "^refactor", group = "Refactoring" }, { message = "^style", group = "Styling" }, { message = "^test", group = "Testing" }, { message = "^chore\\(release\\)", skip = true }, { message = "^chore", group = "Miscellaneous" }, ] filter_commits = false tag_pattern = "v[0-9]*" skip_tags = "" ignore_tags = "" topo_order = false sort_commits = "oldest"
[github] owner = "owner" repo = "repo"
Generate changelog
git cliff -o CHANGELOG.md
Generate for specific range
git cliff v1.0.0..v2.0.0 -o RELEASE_NOTES.md
Preview without writing
git cliff --unreleased --dry-run
### Method 6: Python (commitizen)
pyproject.toml
[tool.commitizen] name = "cz_conventional_commits" version = "1.0.0" version_files = [ "pyproject.toml:version", "src/__init__.py:__version__", ] tag_format = "v$version" update_changelog_on_bump = true changelog_incremental = true changelog_start_rev = "v0.1.0"
[tool.commitizen.customize] message_template = "{{change_type}}{% if scope %}({{scope}}){% endif %}: {{message}}" schema = "<type>(<scope>): <subject>" schema_pattern = "^(feat|fix|docs|style|refactor|perf|test|chore)(\\(\\w+\\))?:\\s.*" bump_pattern = "^(feat|fix|perf|refactor)" bump_map = {"feat" = "MINOR", "fix" = "PATCH", "perf" = "PATCH", "refactor" = "PATCH"}
Install
pip install commitizen
Create commit interactively
cz commit
Bump version and update changelog
cz bump --changelog
Check commits
cz check --rev-range HEAD~5..HEAD
## Release Notes Templates
### GitHub Release Template
What's Changed
🚀 Features
{{ range .Features }}
- {{ .Title }} by @{{ .Author }} in #{{ .PR }}
{{ end }}
🐛 Bug Fixes
{{ range .Fixes }}
- {{ .Title }} by @{{ .Author }} in #{{ .PR }}
{{ end }}
📚 Documentation
{{ range .Docs }}
- {{ .Title }} by @{{ .Author }} in #{{ .PR }}
{{ end }}
🔧 Maintenance
{{ range .Chores }}
- {{ .Title }} by @{{ .Author }} in #{{ .PR }}
{{ end }}
New Contributors
{{ range .NewContributors }}
- @{{ .Username }} made their first contribution in #{{ .PR }}
{{ end }}
Full Changelog: https://github.com/owner/repo/compare/v{{ .Previous }}...v{{ .Current }}
### Internal Release Notes
Release v2.1.0 - January 15, 2024
Related skills
How it compares
Pick changelog-automation when release notes must be derived from git commits; use general documentation skills when writing narrative product docs unrelated to version history.
FAQ
What is Conventional Commits?
Syntax for commit messages (feat, fix, type!) that enables automated changelog generation and semantic versioning. Example: feat(auth): add OAuth2 support.
How do I mark breaking changes?
Use `!` after type/scope (feat(api)!: change response format) or add BREAKING CHANGE: footer in commit body with migration guide.
What is commitlint?
Tool that validates commit messages match Conventional Commits format in CI pipelines, preventing non-standard commits from merging.
Is Changelog Automation safe to install?
skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.