ADR 005: Use AI-Powered Changelog Generation with Gemini
Status
Accepted
Context
The Problem
The current release process forces one release per merge to main, which doesn't work well with high-velocity AI-assisted development. The workflow was:
- Merge PR to main → automatically triggers build and release
- Each merge creates a GitHub release and publishes to Snap edge channel
- Cannot bundle multiple PRs before releasing
- No control over when changes ship to users
Additionally, writing changelog entries manually when preparing releases is:
- Time-consuming (5-10 minutes per release)
- Error-prone (remembering all changes after the fact)
- Inconsistent (varying levels of detail and formatting)
- Done when memory of the PR is fading
Requirements
- Decouple merging from releasing - Merge PRs freely, release when ready
- Bundle multiple PRs - Accumulate changes before releasing
- Maintain quality changelogs - Concise, consistent, user-focused summaries
- LLM-friendly workflow - Easy for AI assistants to help with releases
- Full control - Decide exactly when to ship to snap/flatpak/GitHub
- Low maintenance - Minimal manual work and cost
Research Conducted
Spike 1: Quality Validation
- Tested Gemini 2.0 Flash on 5 real PRs from the repository
- Average quality score: 9.0/10
- Generated summaries averaged 60 characters vs manual 165 characters
- Better consistency and conciseness than manual entries
Spike 2: Implementation Validation
- Tested GitHub Actions permissions for committing to PR branches
- Validated industry-standard workflow pattern
- Confirmed secure implementation without script injection vulnerabilities
Decision
We will implement an AI-powered changelog system using Google's Gemini API to automatically generate one-line changelog entries for each PR.
Architecture
Changelog Staging Area:
.changelog/directory stores pending changelog entries- Each merged PR creates
.changelog/pr-XXX.txtwith AI-generated summary - Files accumulate on PR branches until consumed during release
Workflow:
- PR opened/updated → GitHub Action triggers
- Gemini AI analyzes PR title and description
- Generates concise one-line summary (max 80 chars)
- Creates
.changelog/pr-XXX.txton PR branch - Comments on PR with generated entry
- On merge to main, changelog file comes along
- Repeat for multiple PRs (files accumulate)
- When ready to release:
- Review accumulated
.changelog/*.txtfiles - Update version in package.json and appdata.xml (manually or via script)
- Commit and push → triggers build only when version changes
- Review accumulated
Security Measures:
- Use
actions/github-script@v7to avoid script injection - All user input via
context.payload(never bash interpolation) - Isolated environment with hardcoded PATH for npm operations
- No spreading of
process.envto prevent PATH injection
Alternatives Considered
1. Manual Changelog Entries
Approach: Continue writing changelogs manually when preparing releases
Pros:
- No external dependencies
- Full human control over wording
Cons:
- Time-consuming (5-10 min per release)
- Inconsistent format
- Written when memory is fading
- Human entries averaged 165 chars (too verbose)
Verdict: Rejected - AI produces better quality with less effort
2. Claude AI (Anthropic)
Approach: Use Claude via official GitHub Action
Pros:
- Excellent quality summaries
- Official Anthropic support
Cons:
- Not free (~$0.001 per summary)
- Requires separate API key
Verdict: Rejected - Gemini free tier is sufficient and high quality
3. Release PR Automation
Approach: Fully automated Release PR workflow (like Changesets)
Pros:
- Fully automated version bumping
- Industry-standard pattern
Cons:
- Complex setup
- Less flexibility for manual control
- Overkill for current needs
Verdict: Deferred - Start simple with manual process, automate later if needed
4. Commit to Main After Merge
Approach: Generate changelog and commit to main after PR merge
Pros:
- Simpler workflow
Cons:
- Creates extra commits on main
- Triggers extra CI/CD runs (50% overhead)
- Messy git history
Verdict: Rejected - Commit to PR branch instead
Consequences
Positive
- Decoupled workflow - Can merge multiple PRs before releasing
- Better changelog quality - Concise (60 vs 165 chars), consistent format
- Time savings - 5-10 minutes saved per release
- LLM-friendly - Plain text
.changelog/*.txtfiles easy for AI to read - Full control - Decide exactly when to publish to snap/flatpak/GitHub
- Zero cost - Gemini free tier: 1,500 requests/day (we use ~10-20/month)
- Always editable - Can edit
.changelog/*.txtfiles before releasing
Negative
- External dependency - Relies on Google's Gemini API
- API key management - Must configure
GEMINI_API_KEYin GitHub Secrets - Potential AI errors - Generated summary might be incorrect (mitigated by human review)
- New workflow - Contributors need to understand
.changelog/directory
Neutral
- Manual release process - Still manual (by design for control)
- LLM assistance optional - Can use script or do fully manually
- Gradual adoption - Can edit AI-generated entries or write manually
Implementation
Files Created:
.github/workflows/changelog-generator.yml- Auto-generates entriesscripts/release-prepare.js- Optional script to consume changelogs.changelog/README.md- Quick setup guidedocs-site/docs/development/manual-release-process.md- Release guide
npm Scripts:
{
"release:prepare": "node scripts/release-prepare.js"
}
Manual changelog entries: Users can simply create .changelog/*.txt files directly.
GitHub Action Trigger:
on:
pull_request:
types: [opened, synchronize]
permissions:
contents: write
pull-requests: write
Gemini API Configuration:
- Model:
gemini-2.0-flash-thinking-exp-1219 - Temperature: 0.3 (consistent, less creative)
- Max tokens: 100 (sufficient for one-liner)
- Free tier: 1,500 requests/day
Security Implementation:
- Module-level constant:
SAFE_PATH = '/usr/bin:/bin' - Isolated environment for npm operations
- No user input in shell commands
- All data via
context.payloadin github-script
Validation
Spike 1 Results (Quality):
- Tested on 5 real PRs from repository
- Average quality: 9.0/10
- Average length: 60 chars (vs manual 165 chars)
- Better conciseness and consistency than manual
Spike 2 Results (Implementation):
- GitHub Actions permissions work correctly
- Commits to PR branch successfully
- Workflow triggers appropriately
- Security checks pass (SonarQube)
Production Test:
- Validated on PR #1951 (this implementation)
- Generated entry: "Add AI-powered changelog system to decouple merging from releasing"
- Workflow executed successfully
- File committed to PR branch
Future Considerations
- Full automation - Could implement Release PR workflow later
- Extract as bot - Could package as reusable GitHub Action for other projects
- Build optimization - Could detect version changes to skip unnecessary builds
- Multi-repo support - Could share Gemini API key across multiple repositories
References
- Implementation PR: #1951
- Gemini API Docs: https://ai.google.dev/gemini-api/docs
- Manual Release Process:
docs-site/docs/development/manual-release-process.md - GitHub Actions Security: https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions
Decision Date
2025-11-17
Decision Makers
- @IsmaelMartinez (Project Maintainer)
- Claude Code (Implementation Assistant)