/changelog
Automated changelogs, semantic versioning, and user-friendly release notes. Audit, fix, verify—every time.
What This Does
Examines your release infrastructure, identifies every gap, implements fixes, and verifies the full pipeline works. No partial modes. Every run does the full cycle.
Process
1. Audit
Check what exists and what's broken:
# Configuration
[ -f ".releaserc.js" ] || [ -f ".releaserc.json" ] && echo "✓ semantic-release" || echo "✗ semantic-release"
[ -f "commitlint.config.js" ] || [ -f "commitlint.config.cjs" ] && echo "✓ commitlint" || echo "✗ commitlint"
grep -q "commit-msg" lefthook.yml 2>/dev/null && echo "✓ commit-msg hook" || echo "✗ commit-msg hook"
# GitHub Actions
[ -f ".github/workflows/release.yml" ] && echo "✓ release workflow" || echo "✗ release workflow"
grep -q "semantic-release" .github/workflows/release.yml 2>/dev/null && echo "✓ runs semantic-release" || echo "✗ doesn't run semantic-release"
grep -q "GEMINI_API_KEY" .github/workflows/release.yml 2>/dev/null && echo "✓ LLM synthesis configured" || echo "✗ LLM synthesis missing"
# Public page
ls app/changelog/page.tsx src/app/changelog/page.tsx 2>/dev/null && echo "✓ changelog page" || echo "✗ changelog page"
# Health
gh release list --limit 3 2>/dev/null || echo "✗ no releases"
Commit history check:
git log --oneline -10 | while read line; do
echo "$line" | grep -qE "^[a-f0-9]+ (feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?: " || echo "NON-CONVENTIONAL: $line"
done
2. Plan
From audit findings, build remediation plan. Every project needs:
Must have:
- semantic-release configured with changelog, git, github plugins
- commitlint enforcing conventional commits
- Lefthook commit-msg hook running commitlint
- GitHub Actions workflow running semantic-release on push to main
Should have:
- LLM synthesis transforming technical changelog to user-friendly notes
- Public
/changelogpage fetching from GitHub Releases API - RSS feed at
/changelog.xmlor/changelog/rss
3. Execute
Fix everything. Don't stop at a report.
Installing semantic-release:
pnpm add -D semantic-release @semantic-release/changelog @semantic-release/git @semantic-release/github
Create .releaserc.js:
module.exports = {
branches: ['main'],
plugins: [
'@semantic-release/commit-analyzer',
'@semantic-release/release-notes-generator',
['@semantic-release/changelog', { changelogFile: 'CHANGELOG.md' }],
['@semantic-release/git', { assets: ['CHANGELOG.md', 'package.json'] }],
'@semantic-release/github',
],
};
Installing commitlint:
pnpm add -D @commitlint/cli @commitlint/config-conventional
Create commitlint.config.js:
module.exports = { extends: ['@commitlint/config-conventional'] };
Add to lefthook.yml:
commit-msg:
commands:
commitlint:
run: pnpm commitlint --edit {1}
Creating release workflow:
Create .github/workflows/release.yml per changelog-setup reference.
Adding LLM synthesis:
REQUIRED: Before implementing, read
llm-infrastructure/references/model-research-required.mdDo NOT use model names from this document or your training data. Run the OpenRouter fetch script and web search to determine current best model for this task.
Steps:
-
Research current models (MANDATORY):
# Query OpenRouter for current fast/cheap models python3 ~/.claude/skills/llm-infrastructure/scripts/fetch-openrouter-models.py \ --task fast --filter "google|anthropic|openai" --top 10 # Web search: "best LLM for text summarization 2026" # Web search: "Gemini API current models 2026" -
Create
scripts/synthesize-release-notes.mjsthat:- Fetches latest release from GitHub API
- Uses OpenRouter API (not direct provider APIs) for flexibility
- Model name comes from environment variable, NOT hardcoded
- Gets user-friendly summary back
- Updates release body via GitHub API
-
Configure secrets in GitHub:
OPENROUTER_API_KEY(preferred) or provider-specific key- Model name as environment variable (e.g.,
LLM_MODEL_SYNTHESIS)
Creating public changelog page:
Per changelog-page, create:
app/changelog/page.tsx- Fetches from GitHub Releases API- Groups releases by minor version
- No auth required (public page)
- RSS feed support
Making changelog discoverable (CRITICAL): A changelog page that users can't find is useless. Ensure:
- Footer link: Add "changelog" link to global footer (visible on landing page)
- Settings link: Add "View changelog" link in app settings/about section
- Version display: Show current app version in settings (use
NEXT_PUBLIC_APP_VERSIONenv var) - RSS link: Mention RSS feed on the changelog page itself
Example footer links:
<Link href="/changelog">changelog</Link>
<Link href="/support">support</Link>
<Link href="/privacy">privacy</Link>
Example settings "About" section:
<div className="flex items-center justify-between">
<span>Version</span>
<span className="font-mono">{process.env.NEXT_PUBLIC_APP_VERSION || '0.1.0'}</span>
</div>
<Link href="/changelog">View changelog →</Link>
Delegate implementation to Codex where appropriate.
4. Verify
Prove it works. Not "config exists"—actually works.
Commitlint test:
echo "bad message" | pnpm commitlint
# Should fail
echo "feat: valid message" | pnpm commitlint
# Should pass
Commit hook test:
# Try to commit with bad message (should be rejected)
git commit --allow-empty -m "bad message"
# Should fail due to commitlint hook
Release workflow test: If you can trigger a release:
- Merge a PR with
feat:orfix:commit - Watch GitHub Actions run
- Verify:
- Version bumped in package.json
- CHANGELOG.md updated
- GitHub Release created
- Release notes populated (LLM synthesis ran)
Public page test:
- Navigate to
/changelog - Verify releases displayed
- Verify grouped by minor version
- Check RSS feed works
If any verification fails, go back and fix it.
The Release Flow
Commit with conventional format (enforced by Lefthook)
↓
Push/merge to main
↓
GitHub Actions runs semantic-release
↓
Version bumped, CHANGELOG.md updated, GitHub Release created
↓
Post-release action triggers LLM synthesis
↓
LLM (via OpenRouter) transforms changelog → user notes
↓
Enhanced notes stored in GitHub Release
↓
Public /changelog page displays latest
Key Principles
Every merge is a release. Web apps deploy on merge. Embrace frequent releases.
Every change gets notes. Even chore: commits become "Behind-the-scenes improvements."
Group for readability. Public page groups patches under their minor version.
Auto-publish. No human gate on LLM synthesis. Trust the pipeline.
Default Stack
Assumes Next.js + TypeScript + GitHub. Adapts gracefully to other stacks.
What You Get
When complete:
- semantic-release configured and working
- Conventional commits enforced (can't commit without format)
- GitHub Actions workflow for releases
- LLM synthesis for user-friendly notes (model via env var)
- Public
/changelogpage with RSS feed - Discoverable links from footer and settings
- Version displayed in app settings
- Verified end-to-end
User can:
- Merge a PR with conventional commit
- See automatic version bump
- See GitHub Release created
- See user-friendly notes synthesized
- Find changelog from footer or settings (not hidden)
- See what version they're running
- Subscribe to RSS feed for updates