relnote docs · CHANGELOG.md · Compare · gh relnote

Next semver version and monorepo release notes from conventional commits

Since v0.3.0, relnote can tell you what the next tag should be, and it can scope notes, changelog sections, and versions to one package in a monorepo. It still reads only your local git history: no config file, no API token, no Node.

Install

brew install loki-inu/tap/relnote
# or
pip install git+https://github.com/loki-inu/relnote.git
relnote --version   # relnote 0.3.0

Print the next version

$ git describe --tags --abbrev=0
v1.3.2
$ git log --format=%s v1.3.2..HEAD
fix(cli): handle empty ranges
feat: --next-version flag
$ relnote --next-version
v1.4.0

relnote looks at the commits after the previous tag (or --since) with the same filters as the notes, then bumps that tag:

Commits in rangeBumpv1.3.2 becomesv0.4.2 becomes
type!: or a BREAKING CHANGE: footermajorv2.0.0v0.5.0 (0.x stays 0.x)
any featminorv1.4.0v0.5.0
only fix, docs, chore, otherpatchv1.3.3v0.4.3
no previous tagfirst releasev0.1.0

No commits in the range exits 1 (nothing to release). A previous tag that is not x.y.z also exits 1 with a message, instead of guessing. relnote prints the tag and stops; it never runs git tag.

Use it with the other commands

next="$(relnote --next-version)"
relnote --changelog CHANGELOG.md --changelog-title "$next" -q
git commit -am "chore(release): $next" && git tag "$next"
gh relnote create "$next"     # or: relnote --output notes.md -q && gh release create "$next" --notes-file notes.md

After you tag, plain relnote notices that HEAD is the new tag and uses the tag before it as the start of the range, so the notes cover the release you just made.

Monorepos: one package at a time

Two flags scope everything to a package:

# notes for packages/api since its last api/v* tag
relnote --path packages/api --tag-prefix api/v

# its next version and changelog section
relnote --path packages/api --tag-prefix api/v --next-version        # api/v1.3.0
relnote --path packages/api --tag-prefix api/v   --changelog packages/api/CHANGELOG.md --changelog-title api/v1.3.0 -q

# a package plus shared code
relnote --path packages/web --path packages/shared --tag-prefix web@

GitHub Action

- uses: actions/checkout@v4
  with:
    fetch-depth: 0
- id: relnote
  uses: loki-inu/relnote@v0.3.0
  with:
    path: |
      packages/api
    tag-prefix: api/v
- run: echo "next is ${{ steps.relnote.outputs.next-version }}"

The action outputs notes (the Release body) and next-version (empty if the previous tag is not semver). path takes one directory per line.

Compared to version-bump tools

relnote --next-versionsemantic-release / release-pleasegit-cliff --bumped-version
RuntimePython 3.11 stdlib, gitNode, or a GitHub App / Action with a tokenRust binary
Confignone (flags only)config file and pluginscliff.toml optional
Creates tags / releases / PRsno, prints a suggestionyesno
Monorepo--path + --tag-prefixplugins or manifest config--include-path + tag pattern
Release body / CHANGELOG.mdboth, same commandyesCHANGELOG.md via templates

If you want the whole release automated (version files, tags, PRs, npm publish), keep semantic-release or release-please. relnote is for when you want the answer and the notes, and want to do the tagging yourself.