Changelog-Based Release System
Overview
This repository uses a changelog-based release system. Releases are triggered by updating changelogs and merging to main - no manual tagging required.
Key principle: The changelog is the source of truth for releases. When a new version appears in a changelog and merges to main, the release workflow automatically creates a git tag and triggers the appropriate release pipeline.
Quick Start
# 1. Check if there are changes to release
r2r release pending r2r-cli
# 2. Update the changelog with a new version
r2r release this r2r-cli
# 3. Commit and create a PR
git add release/r2r-cli/CHANGELOG.md
git commit -m "release(r2r-cli): 0.1.0"
git push && gh pr create
# 4. After PR merges, release-auto workflow creates the tag
# 5. Tag triggers the module's release workflow to build and publish
How It Works
Developer
│
▼
┌──────────────────┐
│ release pending │ Check for unreleased changes
└────────┬─────────┘
│
▼
┌──────────────────┐
│ release this │ Update changelog with new version
└────────┬─────────┘
│
▼
┌──────────────────┐
│ Commit & PR │ Create PR for review
└────────┬─────────┘
│
▼
┌──────────────────┐
│ Merge to main │ After approval
└────────┬─────────┘
│
─────────┼─────────────────────────────────────────
│ CI/CD (automated)
▼
┌──────────────────┐
│ release-auto.yml │ Detects new version, creates git tag
└────────┬─────────┘
│
▼
┌──────────────────┐
│ release-*.yml │ Builds and publishes artifacts
└──────────────────┘
Commands
release pending
Check if a module has unreleased changes since the last release tag.
# Check single module
r2r release pending r2r-cli
# Check all modules
r2r release pending --all
# Quiet mode (exit code only: 0=has changes, 1=no changes)
r2r release pending r2r-cli --quiet
Output includes:
has_changes: whether there are releasable changescurrent_version: the current released versionnext_version: the calculated next versionchange_summary: breakdown by change type
release this
Finalize the changelog and prepare a module for release.
# Update changelog
r2r release this r2r-cli
# Preview without writing
r2r release this r2r-cli --dry-run
# Output as JSON
r2r release this r2r-cli --json
This command:
- Analyzes commits since the last release tag
- Generates changelog entries from conventional commits
- Calculates the next version (respecting constraints)
- Updates the changelog with the new version
release tag-pending
Check for changelog versions without corresponding git tags. Used by CI.
release validate
Validate changelog format and structure.
Checks: file exists, valid header format, valid semver/calver, versions in order, no duplicates.
Changelog Format
Changelogs follow Keep a Changelog format.
# Changelog
All notable changes to **module-name** will be documented in this file.
## [Unreleased]
### Added
- Manual entry: something not in a commit
## [0.1.0] - 2024-01-15
### Added
- feat: new feature description
### Fixed
- fix: bug fix description
## [0.0.1] - 2024-01-01
### Added
- Initial release
[Unreleased]: https://github.com/org/repo/compare/module/0.1.0...HEAD
[0.1.0]: https://github.com/org/repo/compare/module/0.0.1...module/0.1.0
Entry Generation
- Most entries are auto-generated from conventional commits
- The
[Unreleased]section is for manual additions (optional) - When you run
release this, manual entries merge with commit-generated entries - After release,
[Unreleased]becomes empty
Change Types
| Type | Description | Conventional Commit |
|---|---|---|
| Added | New features | feat: |
| Changed | Changes to existing functionality | refactor:, perf: |
| Deprecated | Soon-to-be removed features | deprecate: |
| Removed | Removed features | remove: |
| Fixed | Bug fixes | fix: |
| Security | Security fixes | security: |
Versioning
Semver (r2r-cli, ext-eac)
Semantic versioning: MAJOR.MINOR.PATCH
- MAJOR: Breaking changes (
feat!:,fix!:, orBREAKING CHANGE:) - MINOR: New features (
feat:) - PATCH: Bug fixes (
fix:)
Constraints
The .r2r/eac/repository.yml file can constrain version bumps:
versioning:
constraint: patch-only # Only allow patch bumps
constraint: calver-only # Only allow date-based versions
Directory Structure
release/
├── r2r-cli/
│ └── CHANGELOG.md # CLI changelog (semver)
├── ext-eac/
└── CHANGELOG.md # Extension changelog (semver)
Releasable modules place changelogs in release/<module>/CHANGELOG.md. The release-auto workflow watches this directory.
Non-releasable modules can have changelogs elsewhere for documentation only.
GitHub Workflows
| Workflow | Trigger | Action |
|---|---|---|
release-auto.yml |
Push to main with release/*/CHANGELOG.md changes |
Creates git tag |
release-r2r-cli.yml |
r2r-cli/* tag |
Builds CLI binaries, creates GitHub release |
release-ext-eac.yml |
ext-eac/* tag |
Retags container images |
Tag Format
Tags follow the pattern <module>/<version>:
r2r-cli/0.1.0ext-eac/1.0.0
Troubleshooting
"No conventional commits found"
Ensure commits follow the format:
"No commits affecting module found"
Commits are filtered by module file patterns. Ensure changes touch files owned by the module.
Changelog validation errors
Run r2r release validate <module> to check for format issues:
- Invalid version format
- Duplicate versions
- Versions out of order
Next Steps
- Release Notes - How to write effective release notes
- Release Evidence - What evidence is required for approval
- Commit Messages - Conventional commit format
Tutorials | How-to Guides | Explanation | Reference
You are here: Explanation — understanding-oriented discussion that clarifies concepts.