relnote docs · Compare · Offline notes · gh relnote · Next version
Generate CHANGELOG.md from conventional commits, without a config file
relnote reads your git history from the latest tag to HEAD, groups feat, fix, and breaking changes, and prepends one release section to CHANGELOG.md. Your header and older entries are left exactly as they were.
Install
pip install git+https://github.com/loki-inu/relnote.git
relnote --version # relnote 0.3.0
Python 3.11+ and git on PATH. No third-party packages, no network calls, no config file.
On macOS or Linux with Homebrew: brew install loki-inu/tap/relnote.
Add the next release
relnote --changelog CHANGELOG.md --changelog-title v1.3.0
git add CHANGELOG.md && git commit -m "docs: changelog for v1.3.0"
git tag v1.3.0
stdout still prints the GitHub Release body, so one run gives you both. Add -q to only touch the file. Pass --since v1.2.0 to pick the range by hand and --date 2026-10-08 to pin the date (default is today in UTC). Without --changelog-title, the title is the --until ref, or Unreleased when that is HEAD.
What gets written
# Changelog
All notable changes to this project are documented in this file.
## [v1.3.0] - 2026-10-08
### Breaking
- **api:** drop the v1 endpoint (`a1b2c3d`) — Ada Lovelace
- BREAKING CHANGE: clients must call /v2
### Features
- **cli:** add --json output (`d4e5f6a`) — Ada Lovelace
### Fixes
- handle empty config (`b7c8d9e`) — Grace Hopper
**Full changelog:** https://github.com/you/project/compare/v1.2.0...v1.3.0
## [v1.2.0] - 2026-09-01
…
Illustrative output from a made-up history. A missing file is created with the # Changelog header. The new section goes above the first ## heading, after any preamble. The compare link appears when origin is a github.com remote.
Safe to re-run
- If
CHANGELOG.mdalready has## [v1.3.0], relnote exits 1 and changes nothing. A retried CI job cannot add the release twice. - An empty range (no commits after filters) exits 1 before the file is touched.
- Merge commits are skipped by default,
--no-botsdrops dependabot and renovate, and subjects that look like tokens or keys are never written.
In GitHub Actions
- uses: actions/checkout@v4
with:
fetch-depth: 0
- id: relnote
uses: loki-inu/relnote@v0.3.0
with:
changelog: CHANGELOG.md
changelog-title: ${{ github.ref_name }}
# then commit CHANGELOG.md in a later step or open a PR with it
The notes output is still the Release body. The action edits the file in the runner only; committing it is up to your workflow.
With the GitHub CLI
gh extension install loki-inu/gh-relnote
gh relnote create v1.3.0 --draft -- --changelog CHANGELOG.md --changelog-title v1.3.0
Creates the draft Release and updates CHANGELOG.md from the same notes. See gh relnote.
relnote vs git-cliff for CHANGELOG.md
relnote --changelog | git-cliff | |
|---|---|---|
| Config | None | cliff.toml with Tera templates |
| How the file changes | Prepends the new release only | Regenerates from history, or prepends with --prepend |
| Install | Stdlib Python, or the gh extension | Rust binary, cargo, npm, pip, and more |
| Release body too | Yes, same run, on stdout | Separate invocation or template |
| Version bump | Prints it: --next-version (details) | Yes, --bump |
Pick git-cliff if you want custom templates, commit parsers, or a computed next version. Pick relnote if you want sensible Keep a Changelog sections and a Release body with nothing to configure.