Changelog Automation
Automate changelog generation and release workflows with industry standards
✨ The solution you've been looking for
Automate changelog generation from commits, PRs, and releases following Keep a Changelog format. Use when setting up release workflows, generating release notes, or standardizing commit conventions.
See It In Action
Interactive preview & real-world examples
AI Conversation Simulator
See how users interact with this skill
User Prompt
I need to set up automated changelog generation for my Node.js project. We want to follow conventional commits and generate release notes automatically on GitHub.
Skill Processing
Analyzing request...
Agent Response
Complete setup with commitlint, husky hooks, standard-version or semantic-release configuration, and GitHub Actions workflow for automated releases
Quick Start (3 Steps)
Get up and running in minutes
Install
claude-code skill install changelog-automation
claude-code skill install changelog-automationConfig
First Trigger
@changelog-automation helpCommands
| Command | Description | Required Args |
|---|---|---|
| @changelog-automation setup-automated-changelog-generation | Implement conventional commits and automated changelog generation for a project using semantic versioning | None |
| @changelog-automation standardize-commit-message-format | Establish team conventions for commit messages and enforce them through tooling | None |
| @changelog-automation generate-release-notes-from-git-history | Create professional release notes and changelogs from existing commit history | None |
Typical Use Cases
Setup Automated Changelog Generation
Implement conventional commits and automated changelog generation for a project using semantic versioning
Standardize Commit Message Format
Establish team conventions for commit messages and enforce them through tooling
Generate Release Notes from Git History
Create professional release notes and changelogs from existing commit history
Overview
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
1# Changelog
2
3All notable changes to this project will be documented in this file.
4
5The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
8## [Unreleased]
9
10### Added
11
12- New feature X
13
14## [1.2.0] - 2024-01-15
15
16### Added
17
18- User profile avatars
19- Dark mode support
20
21### Changed
22
23- Improved loading performance by 40%
24
25### Deprecated
26
27- Old authentication API (use v2)
28
29### Removed
30
31- Legacy payment gateway
32
33### Fixed
34
35- Login timeout issue (#123)
36
37### Security
38
39- Updated dependencies for CVE-2024-1234
40
41[Unreleased]: https://github.com/user/repo/compare/v1.2.0...HEAD
42[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)
1# Install tools
2npm install -D @commitlint/cli @commitlint/config-conventional
3npm install -D husky
4npm install -D standard-version
5# or
6npm install -D semantic-release
7
8# Setup commitlint
9cat > commitlint.config.js << 'EOF'
10module.exports = {
11 extends: ['@commitlint/config-conventional'],
12 rules: {
13 'type-enum': [
14 2,
15 'always',
16 [
17 'feat',
18 'fix',
19 'docs',
20 'style',
21 'refactor',
22 'perf',
23 'test',
24 'chore',
25 'ci',
26 'build',
27 'revert',
28 ],
29 ],
30 'subject-case': [2, 'never', ['start-case', 'pascal-case', 'upper-case']],
31 'subject-max-length': [2, 'always', 72],
32 },
33};
34EOF
35
36# Setup husky
37npx husky init
38echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg
Method 2: standard-version Configuration
1// .versionrc.js
2module.exports = {
3 types: [
4 { type: "feat", section: "Features" },
5 { type: "fix", section: "Bug Fixes" },
6 { type: "perf", section: "Performance Improvements" },
7 { type: "revert", section: "Reverts" },
8 { type: "docs", section: "Documentation", hidden: true },
9 { type: "style", section: "Styles", hidden: true },
10 { type: "chore", section: "Miscellaneous", hidden: true },
11 { type: "refactor", section: "Code Refactoring", hidden: true },
12 { type: "test", section: "Tests", hidden: true },
13 { type: "build", section: "Build System", hidden: true },
14 { type: "ci", section: "CI/CD", hidden: true },
15 ],
16 commitUrlFormat: "{{host}}/{{owner}}/{{repository}}/commit/{{hash}}",
17 compareUrlFormat:
18 "{{host}}/{{owner}}/{{repository}}/compare/{{previousTag}}...{{currentTag}}",
19 issueUrlFormat: "{{host}}/{{owner}}/{{repository}}/issues/{{id}}",
20 userUrlFormat: "{{host}}/{{user}}",
21 releaseCommitMessageFormat: "chore(release): {{currentTag}}",
22 scripts: {
23 prebump: 'echo "Running prebump"',
24 postbump: 'echo "Running postbump"',
25 prechangelog: 'echo "Running prechangelog"',
26 postchangelog: 'echo "Running postchangelog"',
27 },
28};
1// package.json scripts
2{
3 "scripts": {
4 "release": "standard-version",
5 "release:minor": "standard-version --release-as minor",
6 "release:major": "standard-version --release-as major",
7 "release:patch": "standard-version --release-as patch",
8 "release:dry": "standard-version --dry-run"
9 }
10}
Method 3: semantic-release (Full Automation)
1// release.config.js
2module.exports = {
3 branches: [
4 "main",
5 { name: "beta", prerelease: true },
6 { name: "alpha", prerelease: true },
7 ],
8 plugins: [
9 "@semantic-release/commit-analyzer",
10 "@semantic-release/release-notes-generator",
11 [
12 "@semantic-release/changelog",
13 {
14 changelogFile: "CHANGELOG.md",
15 },
16 ],
17 [
18 "@semantic-release/npm",
19 {
20 npmPublish: true,
21 },
22 ],
23 [
24 "@semantic-release/github",
25 {
26 assets: ["dist/**/*.js", "dist/**/*.css"],
27 },
28 ],
29 [
30 "@semantic-release/git",
31 {
32 assets: ["CHANGELOG.md", "package.json"],
33 message:
34 "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}",
35 },
36 ],
37 ],
38};
Method 4: GitHub Actions Workflow
1# .github/workflows/release.yml
2name: Release
3
4on:
5 push:
6 branches: [main]
7 workflow_dispatch:
8 inputs:
9 release_type:
10 description: "Release type"
11 required: true
12 default: "patch"
13 type: choice
14 options:
15 - patch
16 - minor
17 - major
18
19permissions:
20 contents: write
21 pull-requests: write
22
23jobs:
24 release:
25 runs-on: ubuntu-latest
26 steps:
27 - uses: actions/checkout@v4
28 with:
29 fetch-depth: 0
30 token: ${{ secrets.GITHUB_TOKEN }}
31
32 - uses: actions/setup-node@v4
33 with:
34 node-version: "20"
35 cache: "npm"
36
37 - run: npm ci
38
39 - name: Configure Git
40 run: |
41 git config user.name "github-actions[bot]"
42 git config user.email "github-actions[bot]@users.noreply.github.com"
43
44 - name: Run semantic-release
45 env:
46 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
47 NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
48 run: npx semantic-release
49
50 # Alternative: manual release with standard-version
51 manual-release:
52 if: github.event_name == 'workflow_dispatch'
53 runs-on: ubuntu-latest
54 steps:
55 - uses: actions/checkout@v4
56 with:
57 fetch-depth: 0
58
59 - uses: actions/setup-node@v4
60 with:
61 node-version: "20"
62
63 - run: npm ci
64
65 - name: Configure Git
66 run: |
67 git config user.name "github-actions[bot]"
68 git config user.email "github-actions[bot]@users.noreply.github.com"
69
70 - name: Bump version and generate changelog
71 run: npx standard-version --release-as ${{ inputs.release_type }}
72
73 - name: Push changes
74 run: git push --follow-tags origin main
75
76 - name: Create GitHub Release
77 uses: softprops/action-gh-release@v1
78 with:
79 tag_name: ${{ steps.version.outputs.tag }}
80 body_path: RELEASE_NOTES.md
81 generate_release_notes: true
Method 5: git-cliff (Rust-based, Fast)
1# cliff.toml
2[changelog]
3header = """
4# Changelog
5
6All notable changes to this project will be documented in this file.
7
8"""
9body = """
10{% if version %}\
11 ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
12{% else %}\
13 ## [Unreleased]
14{% endif %}\
15{% for group, commits in commits | group_by(attribute="group") %}
16 ### {{ group | upper_first }}
17 {% for commit in commits %}
18 - {% if commit.scope %}**{{ commit.scope }}:** {% endif %}\
19 {{ commit.message | upper_first }}\
20 {% if commit.github.pr_number %} ([#{{ commit.github.pr_number }}](https://github.com/owner/repo/pull/{{ commit.github.pr_number }})){% endif %}\
21 {% endfor %}
22{% endfor %}
23"""
24footer = """
25{% for release in releases -%}
26 {% if release.version -%}
27 {% if release.previous.version -%}
28 [{{ release.version | trim_start_matches(pat="v") }}]: \
29 https://github.com/owner/repo/compare/{{ release.previous.version }}...{{ release.version }}
30 {% endif -%}
31 {% else -%}
32 [unreleased]: https://github.com/owner/repo/compare/{{ release.previous.version }}...HEAD
33 {% endif -%}
34{% endfor %}
35"""
36trim = true
37
38[git]
39conventional_commits = true
40filter_unconventional = true
41split_commits = false
42commit_parsers = [
43 { message = "^feat", group = "Features" },
44 { message = "^fix", group = "Bug Fixes" },
45 { message = "^doc", group = "Documentation" },
46 { message = "^perf", group = "Performance" },
47 { message = "^refactor", group = "Refactoring" },
48 { message = "^style", group = "Styling" },
49 { message = "^test", group = "Testing" },
50 { message = "^chore\\(release\\)", skip = true },
51 { message = "^chore", group = "Miscellaneous" },
52]
53filter_commits = false
54tag_pattern = "v[0-9]*"
55skip_tags = ""
56ignore_tags = ""
57topo_order = false
58sort_commits = "oldest"
59
60[github]
61owner = "owner"
62repo = "repo"
1# Generate changelog
2git cliff -o CHANGELOG.md
3
4# Generate for specific range
5git cliff v1.0.0..v2.0.0 -o RELEASE_NOTES.md
6
7# Preview without writing
8git cliff --unreleased --dry-run
Method 6: Python (commitizen)
1# pyproject.toml
2[tool.commitizen]
3name = "cz_conventional_commits"
4version = "1.0.0"
5version_files = [
6 "pyproject.toml:version",
7 "src/__init__.py:__version__",
8]
9tag_format = "v$version"
10update_changelog_on_bump = true
11changelog_incremental = true
12changelog_start_rev = "v0.1.0"
13
14[tool.commitizen.customize]
15message_template = "{{change_type}}{% if scope %}({{scope}}){% endif %}: {{message}}"
16schema = "<type>(<scope>): <subject>"
17schema_pattern = "^(feat|fix|docs|style|refactor|perf|test|chore)(\\(\\w+\\))?:\\s.*"
18bump_pattern = "^(feat|fix|perf|refactor)"
19bump_map = {"feat" = "MINOR", "fix" = "PATCH", "perf" = "PATCH", "refactor" = "PATCH"}
1# Install
2pip install commitizen
3
4# Create commit interactively
5cz commit
6
7# Bump version and update changelog
8cz bump --changelog
9
10# Check commits
11cz check --rev-range HEAD~5..HEAD
Release Notes Templates
GitHub Release Template
1## What's Changed
2
3### 🚀 Features
4
5{{ range .Features }}
6
7- {{ .Title }} by @{{ .Author }} in #{{ .PR }}
8 {{ end }}
9
10### 🐛 Bug Fixes
11
12{{ range .Fixes }}
13
14- {{ .Title }} by @{{ .Author }} in #{{ .PR }}
15 {{ end }}
16
17### 📚 Documentation
18
19{{ range .Docs }}
20
21- {{ .Title }} by @{{ .Author }} in #{{ .PR }}
22 {{ end }}
23
24### 🔧 Maintenance
25
26{{ range .Chores }}
27
28- {{ .Title }} by @{{ .Author }} in #{{ .PR }}
29 {{ end }}
30
31## New Contributors
32
33{{ range .NewContributors }}
34
35- @{{ .Username }} made their first contribution in #{{ .PR }}
36 {{ end }}
37
38**Full Changelog**: https://github.com/owner/repo/compare/v{{ .Previous }}...v{{ .Current }}
Internal Release Notes
1# Release v2.1.0 - January 15, 2024
2
3## Summary
4
5This release introduces dark mode support and improves checkout performance
6by 40%. It also includes important security updates.
7
8## Highlights
9
10### 🌙 Dark Mode
11
12Users can now switch to dark mode from settings. The preference is
13automatically saved and synced across devices.
14
15### ⚡ Performance
16
17- Checkout flow is 40% faster
18- Reduced bundle size by 15%
19
20## Breaking Changes
21
22None in this release.
23
24## Upgrade Guide
25
26No special steps required. Standard deployment process applies.
27
28## Known Issues
29
30- Dark mode may flicker on initial load (fix scheduled for v2.1.1)
31
32## Dependencies Updated
33
34| Package | From | To | Reason |
35| ------- | ------- | ------- | ------------------------ |
36| react | 18.2.0 | 18.3.0 | Performance improvements |
37| lodash | 4.17.20 | 4.17.21 | Security patch |
Commit Message Examples
1# Feature with scope
2feat(auth): add OAuth2 support for Google login
3
4# Bug fix with issue reference
5fix(checkout): resolve race condition in payment processing
6
7Closes #123
8
9# Breaking change
10feat(api)!: change user endpoint response format
11
12BREAKING CHANGE: The user endpoint now returns `userId` instead of `id`.
13Migration guide: Update all API consumers to use the new field name.
14
15# Multiple paragraphs
16fix(database): handle connection timeouts gracefully
17
18Previously, connection timeouts would cause the entire request to fail
19without retry. This change implements exponential backoff with up to
203 retries before failing.
21
22The timeout threshold has been increased from 5s to 10s based on p99
23latency analysis.
24
25Fixes #456
26Reviewed-by: @alice
Best 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
Resources
What Users Are Saying
Real feedback from the community
Environment Matrix
Dependencies
Framework Support
Context Window
Security & Privacy
Information
- Author
- wshobson
- Updated
- 2026-01-30
- Category
- productivity-tools
Related Skills
Changelog Automation
Automate changelog generation from commits, PRs, and releases following Keep a Changelog format. Use …
View Details →Changelog
Maintains IdeaVim changelog (CHANGES.md) and build.gradle.kts changeNotes. Use when updating …
View Details →Changelog
Maintains IdeaVim changelog (CHANGES.md) and build.gradle.kts changeNotes. Use when updating …
View Details →