In modern development, managing CHANGELOG.md files and manual version bumping is a recipe for merge conflicts and human error.
@runespoorstack/changelog-manager (invoked via the rune command) is a specialized CLI designed for Trunk Based Development. It shifts the responsibility of documenting changes to the moment the code is written, using a "change file" architecture that ensures smooth CI/CD automation and conflict-free merges.
- Overview
- Core Workflow
- Command Reference
- Installation & Setup
- CI/CD Integration (GitHub Actions)
- Security: Why do we need a PAT?
- Data Structure
- Support & Contributing
The tool operates on a simple three-step lifecycle:
- Document (
rune change): The developer describes the change locally. A small JSON "change file" is created. - Verify (
rune verify): The CI ensures that a change file exists before allowing a Merge Request to pass. - Apply (
rune apply): Upon merging to the main branch, the CI consumes all change files, bumps the version, updates the Markdown, and deletes the temporary files.
The "Intent" Phase. Run this before you commit your code.
It starts an interactive prompt to capture the essence of your work. It checks if your branch is ahead of the target branch and generates a unique file: <branch-name>_yyyy-mm-dd-hh-mm-ss-ms.json.
Change Types Definition:
| Type | Description | Version Impact |
|---|---|---|
| MAJOR | Breaking changes (API renames, removing parameters). | 1.0.0 β 2.0.0 |
| MINOR | New features, backward compatible (new APIs). | 1.0.0 β 1.1.0 |
| PATCH | Bug fixes or private logic updates. | 1.0.0 β 1.0.1 |
| NONE | Tooling, refactoring, or internal config (ESLint, etc). | No Bump |
Tip
Use the --issueLinkPattern flag (e.g., https://jira.com/browse/{{issueId}}) to automatically turn issue IDs into clickable links in your final changelog.
The "Gatekeeper" Phase. Integrate this into your Pull Request / Merge Request CI.
It validates that the developer has provided documentation for their changes.
- Success: If no new commits are found or if a valid change file exists.
- Failure: If there are new commits but no change file (or an invalidly named one).
The "Execution" Phase. Integrate this into your Main Branch CI.
This command performs the heavy lifting:
- Calculates the aggregate version bump (e.g., if there are 5 patches and 1 major, it bumps to the next Major).
- Updates
package.jsonwith the new version. - Appends entries to
CHANGELOG.mdandCHANGELOG.json. - Cleans up by deleting the processed change files.
- Commits and Pushes the updates back to the repository using
[ci skip].
npm install --save-dev @runespoorstack/changelog-manager
Add the following to your package.json:
{
"scripts": {
"changelog:change": "rune change --issueLinkPattern https://jira.com/browse/{{issueId}}",
"changelog:verify": "rune verify",
"changelog:apply": "rune apply"
}
}
Place this at the beginning of your pipeline to fail fast if documentation is missing.
jobs:
changelog-verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- name: Verify Documentation
run: npm run changelog:verify -- --sourceBranch origin/${{ github.head_ref || github.ref_name }} --remoteName origin
Place this at the end of your pipeline after tests have passed.
jobs:
changelog-apply:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.PAT_TOKEN }} # Needs push access
- run: |
git config --global user.name "RunespoorBot"
git config --global user.email "bot@runespoor.com"
- run: npm ci
- name: Release Version
run: npm run changelog:apply
The standard GITHUB_TOKEN provided by GitHub Actions is designed for "read-only" or limited internal actions to prevent unintended recursive triggers.
We require a Personal Access Token (PAT) specifically to push commits back to your repository. When rune apply updates your package.json and CHANGELOG.md, it needs write access to the repository to save those changes.
- Go to GitHub Settings > Developer settings.
- Select Personal access tokens > Tokens (classic).
- Click Generate new token.
- Select the
reposcope (this allows the bot to push commits to your repository). - Copy the token and save it in your repository under Settings > Secrets and variables > Actions as
PAT_TOKEN.
Note
For more details, see the official GitHub Documentation on creating a Personal Access Token.
The tool maintains a structured history for programmatic use:
[
{
"version": "1.1.0",
"date": "Tue, 03 Jan 2026 10:00:00 GMT",
"type": "minor",
"comment": "Added high-performance storage engine",
"author": "BorisShulyak",
"issueLinks": ["https://jira.com/browse/RS-42"]
}
]
The generated markdown is clean and human-readable:
## 1.1.0
Tue, 03 Jan 2026 10:00:00 GMT
### MINOR
Added high-performance storage engine
Author: **BorisShulyak**
- https://jira.com/browse/RS-42
We welcome contributions! Please see our CONTRIBUTING.md.
If this tool saves you from merge-conflict headaches, consider supporting the maintainer: π Buy Boris a book
I want to say thank you to the best woman in the world, my wife Diana for her love, daily support, motivation and inspiration.