Changelog Generator
Automated changelog generation from Conventional Commits with semantic versioning and GitHub Release integration for NodeJS-Starter-V1.
Metadata
| Field | Value |
|---|---|
| Skill ID | changelog-generator |
| Category | Communication & Reporting |
| Complexity | Low |
| Complements | ci-cd-patterns |
| Version | 1.0.0 |
| Locale | en-AU |
Description
Codifies automated changelog generation for NodeJS-Starter-V1: parsing Conventional Commits into structured CHANGELOG.md entries, semantic version bumping (major/minor/patch), GitHub Release creation, CI/CD integration for tag-triggered changelog generation, and monorepo-aware grouping.
When to Apply
Positive Triggers
- Creating or updating CHANGELOG.md from git history
- Setting up automated changelog generation in CI/CD
- Configuring semantic version bumping based on commit types
- Creating GitHub Releases with generated release notes
- Adding
standard-versionorconventional-changelogtooling
Negative Triggers
- Writing commit messages (use project commit conventions from
workflow.mdinstead) - CI/CD pipeline architecture (use
ci-cd-patternsskill instead) - Manual release notes for marketing (not a technical changelog)
Core Principles
The Three Laws of Changelogs
- Machine-Parseable, Human-Readable: Generated from structured commits but formatted for developers to scan quickly. Group by type, sort by impact.
- Every User-Facing Change Documented: Features, fixes, and breaking changes must appear. Internal refactors and CI changes may be excluded.
- Linked to Source: Every entry links to its commit or PR. Every release links to the full diff.
Pattern 1: Conventional Commits Parsing
Commit Type → Changelog Section Mapping
Project Reference: Recent git history follows type(scope): description convention consistently.
| Commit Type | Changelog Section | Version Bump | Include? |
|---|---|---|---|
feat |
Features | minor | Always |
fix |
Bug Fixes | patch | Always |
perf |
Performance | patch | Always |
BREAKING CHANGE |
Breaking Changes | major | Always |
docs |
Documentation | — | Optional |
refactor |
Refactoring | — | Optional |
test |
Tests | — | Never |
chore |
Chores | — | Never |
ci |
CI/CD | — | Never |
Breaking Change Detection
Breaking changes are detected via:
BREAKING CHANGE:in commit body or footer!after type/scope:feat(auth)!: remove password login- Commit type
BREAKING CHANGE(rare, non-standard)
Rule: Any commit with a breaking change indicator triggers a major version bump, regardless of the commit type prefix.
Pattern 2: CHANGELOG.md Format
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).
## [Unreleased]
### Features
- **skills**: Generate queue-worker skill via Skill Manager ([2a5e843])
### Bug Fixes
- **hooks**: Correctly parse Beads ready output in stop hook ([1c6953b])
## [1.0.0] - 13/02/2026
### Features
- Complete Environment Isolation Layer + All Project Files ([fed9c50])
- Add Claude Code Hooks and Builder/Validator Pattern ([a22d5a7])
[Unreleased]: https://github.com/CleanExpo/NodeJS-Starter-V1/compare/v1.0.0...HEAD
[1.0.0]: https://github.com/CleanExpo/NodeJS-Starter-V1/releases/tag/v1.0.0
Formatting Rules
| Rule | Example |
|---|---|
| Date format | DD/MM/YYYY (en-AU) |
| Scope in bold | **skills**: description |
| Short hash link | ([abc1234]) linking to commit |
| Sections ordered | Breaking Changes → Features → Bug Fixes → Performance |
| Empty sections omitted | Do not include ### Bug Fixes if there are none |
Pattern 3: Tooling Setup
Option A: standard-version (Recommended)
pnpm add -D standard-version -w
// package.json
{
"scripts": {
"release": "standard-version",
"release:minor": "standard-version --release-as minor",
"release:major": "standard-version --release-as major",
"release:dry-run": "standard-version --dry-run"
}
}
Configuration in .versionrc.json:
{
"types": [
{ "type": "feat", "section": "Features" },
{ "type": "fix", "section": "Bug Fixes" },
{ "type": "perf", "section": "Performance" },
{ "type": "docs", "section": "Documentation", "hidden": true },
{ "type": "refactor", "hidden": true },
{ "type": "test", "hidden": true },
{ "type": "chore", "hidden": true },
{ "type": "ci", "hidden": true }
],
"commitUrlFormat": "https://github.com/CleanExpo/NodeJS-Starter-V1/commit/{{hash}}",
"compareUrlFormat": "https://github.com/CleanExpo/NodeJS-Starter-V1/compare/{{previousTag}}...{{currentTag}}"
}
What pnpm run release does:
- Reads commits since last tag (
v1.0.0) - Determines version bump from commit types
- Updates
package.jsonversion - Generates/updates
CHANGELOG.md - Creates git commit:
chore(release): 1.1.0 - Creates git tag:
v1.1.0
Option B: conventional-changelog CLI
# Generate changelog without version bump
pnpm dlx conventional-changelog -p angular -i CHANGELOG.md -s
Use this for one-off generation without the full release workflow.
Pattern 4: CI/CD Integration
GitHub Actions Workflow
# .github/workflows/release.yml
name: Release
on:
push:
tags:
- "v*"
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for changelog
- name: Generate release notes
id: changelog
run: |
# Extract current version's changelog section
VERSION=${GITHUB_REF#refs/tags/v}
NOTES=$(sed -n "/## \[${VERSION}\]/,/## \[/p" CHANGELOG.md | head -n -1)
echo "notes<<EOF" >> $GITHUB_OUTPUT
echo "$NOTES" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
body: ${{ steps.changelog.outputs.notes }}
generate_release_notes: false
Complements: ci-cd-patterns skill — this workflow follows the project's optional-secret pattern (no secrets required for public release notes) and path-filter conventions.
Project Reference: .github/workflows/ — add release.yml alongside existing ci.yml, security.yml, and agent-pr-checks.yml.
Pattern 5: Release Workflow
Manual Release Process
# 1. Ensure main is clean and up to date
git checkout main && git pull
# 2. Dry run to preview changes
pnpm run release:dry-run
# 3. Execute release (updates CHANGELOG, bumps version, creates tag)
pnpm run release
# 4. Push commit and tag
git push --follow-tags origin main
Automated Release Process
For fully automated releases, use the CI workflow above. When a tag is pushed:
- CI generates release notes from CHANGELOG.md
- GitHub Release is created automatically
- No manual intervention required after
git push --follow-tags
Version Bump Decision Tree
Has BREAKING CHANGE? ──yes──► Major (X.0.0)
│
no
│
Has feat commits? ──yes──► Minor (0.X.0)
│
no
│
Has fix/perf commits? ──yes──► Patch (0.0.X)
│
no
│
No version bump needed
Pattern 6: Monorepo Considerations
Unified Changelog (Recommended for This Project)
Since NodeJS-Starter-V1 is a monorepo (Turborepo), use a single root-level CHANGELOG.md with scope-based grouping:
## [1.2.0] - 15/03/2026
### Features
- **web**: Add dark mode toggle ([abc1234])
- **backend**: Add rate limiting middleware ([def5678])
- **skills**: Generate retry-strategy skill ([356b5ce])
### Bug Fixes
- **backend**: Resolve agent timeout on large prompts ([ghi9012])
The (scope) from Conventional Commits naturally groups entries by package. No per-package changelogs needed unless packages are published independently to npm/PyPI.
Anti-Patterns
| Pattern | Problem | Correct Approach |
|---|---|---|
| Manual changelog editing | Drift from git history, human error | Generate from commits automatically |
| No version tags | Cannot determine version boundaries | Tag every release: v1.0.0, v1.1.0 |
Including chore/ci/test |
Noise for consumers; not user-facing | Hide non-user-facing types |
| US date format in changelog | Inconsistent with project locale | Use DD/MM/YYYY (en-AU) |
| Shallow clone in CI | Missing history breaks changelog generation | Use fetch-depth: 0 |
| Changelog without diff links | No way to see full changes | Include [Unreleased] and version comparison URLs |
Checklist
Before merging changelog changes:
-
standard-versionorconventional-changeloginstalled as devDependency -
.versionrc.jsonconfigured with correct commit type → section mapping -
releasescript added to rootpackage.json - CHANGELOG.md follows Keep a Changelog format
- Dates use DD/MM/YYYY (en-AU locale)
- Version comparison URLs point to correct GitHub repository
- CI workflow creates GitHub Release on tag push
-
fetch-depth: 0used in checkout step for full git history - Dry-run tested:
pnpm run release:dry-run
Response Format
When applying this skill, structure implementation as:
### Changelog Implementation
**Tool**: [standard-version / conventional-changelog / custom]
**Scope**: [unified / per-package]
**Included Types**: [feat, fix, perf]
**Hidden Types**: [docs, refactor, test, chore, ci]
**Date Format**: DD/MM/YYYY
**CI Integration**: [tag-triggered release.yml / manual]
**GitHub Release**: [enabled / disabled]