relnote docs · Single file · gh relnote · CHANGELOG.md · CI

relnote on Windows and PowerShell

relnote turns a git range into GitHub release notes or a Keep a Changelog section. It is plain Python, so it runs on Windows as it does elsewhere. The one thing to know: write files with --output, not >, if you use Windows PowerShell 5.1.

Install

With Scoop:

scoop bucket add loki-inu https://github.com/loki-inu/scoop-bucket
scoop install loki-inu/relnote
scoop install python     # if you do not have Python 3.11+ yet
relnote --version        # relnote 0.3.7

Without Scoop, download the single-file zipapp and run it with the Python launcher:

curl.exe -fsSL -o relnote.pyz https://github.com/loki-inu/relnote/releases/latest/download/relnote.pyz
py -3 relnote.pyz --version

Or pip install git+https://github.com/loki-inu/relnote.git. You also need git on PATH (Git for Windows is fine). Run the commands below inside the repository, after git fetch --tags.

Write notes to a file: use --output

relnote --output notes.md --quiet

relnote writes notes.md itself: UTF-8, no BOM, LF line endings, whatever shell you use. Redirection is different, because PowerShell sits between relnote and the file:

CommandPowerShell 7 (pwsh)Windows PowerShell 5.1
relnote --output notes.md -qUTF-8, no BOM, LFUTF-8, no BOM, LF
relnote > notes.mdUTF-8 (bytes passed through)UTF-16LE with BOM, and accents garbled
relnote | Out-File -Encoding utf8 notes.mdaccents garbledUTF-8 with BOM, accents garbled
$notes = relnoteaccents garbledaccents garbled

That is with the default console code page of a Western-European or US Windows install (437 or 850). PowerShell decodes a native program's output with [Console]::OutputEncoding; relnote writes UTF-8, so é, → and non-Latin names in commit subjects come out wrong when PowerShell re-reads them. Windows PowerShell 5.1 then also writes > as UTF-16. A UTF-16 file passed to gh release create --notes-file shows up as garbage, and a BOM can end up as a stray character at the top of a Release body. --output avoids all of it because relnote writes the file itself.

If you want to capture the text in a variable or pipe it on, switch the console to UTF-8 first (or put this line in your $PROFILE):

[Console]::OutputEncoding = [Text.Encoding]::UTF8
$notes = relnote   # text intact in pwsh and 5.1

With that setting, pwsh's Out-File -Encoding utf8 is fine too; in 5.1, > is still UTF-16 and Out-File -Encoding utf8 still adds a BOM. All of the above was checked on GitHub's windows-latest runner (PowerShell 7.6 and Windows PowerShell 5.1), with code page 437 and with UTF-8.

Printing to the console is fine either way: from v0.3.1 relnote switches its own output to UTF-8 when it is piped or redirected, so it no longer crashes on cp1252 code pages.

Create a GitHub Release from PowerShell

$tag = relnote --next-version          # e.g. v1.4.0, from feat/fix/breaking commits
relnote --output notes.md --quiet
git tag $tag
git push origin $tag
gh release create $tag --notes-file notes.md --title $tag

--next-version prints one tag (breaking → major, feat → minor, otherwise patch) and never tags anything itself. See next version and monorepos for --path and --tag-prefix.

CHANGELOG.md

relnote --changelog CHANGELOG.md --changelog-title $tag --quiet

This prepends a ## [v1.4.0] - YYYY-MM-DD section and leaves older entries alone. From v0.3.2 it also keeps the file's line endings: an LF file stays LF and a CRLF file stays CRLF, so the diff is only the new section. (v0.3.1 and earlier rewrote an LF file with CRLF on Windows, which showed up as a whole-file change when core.autocrlf is off.) New files are created with LF. More in CHANGELOG.md from conventional commits.

gh extension and Git Bash

gh relnote is a bash script. It works on Windows with Git for Windows installed; it was checked from Git Bash with gh 2.102:

gh extension install loki-inu/gh-relnote
gh relnote create v1.4.0 --draft

examples/release.sh (bump version file, update CHANGELOG.md, commit, tag) also needs bash. From Git Bash, point it at the zipapp:

RELNOTE="python relnote.pyz" bash examples/release.sh --bump-file package.json

The version bump keeps package.json's own line endings too (v0.3.2).

In a Windows CI job

- uses: actions/checkout@v4
  with:
    fetch-depth: 0
- uses: actions/setup-python@v5
  with:
    python-version: "3.12"
- name: Release notes
  shell: pwsh
  run: |
    curl.exe -fsSL -o relnote.pyz https://github.com/loki-inu/relnote/releases/download/v0.3.7/relnote.pyz
    python relnote.pyz --output notes.md --quiet

The full history and tags are needed (fetch-depth: 0). On Linux runners the GitHub Action is simpler; other CI systems are on the CI page.

How this page is tested

relnote's CI runs scripts/windows-check.ps1 under both pwsh and Windows PowerShell 5.1 on every push: --output must produce UTF-8 without BOM or CR bytes under code page 437, captured text must survive once the console is UTF-8, --next-version must be right, and --changelog must keep an LF file LF. The Scoop bucket's CI installs relnote with Scoop and generates notes on Windows.