Skip to content
rasmusp.com

Release-it — Automation for versioning and changelog

You’ve just merged the last feature of the sprint, eager to ship it to your app. Everything looks great, and you are ready to deploy, but now you’re stuck manually bumping the version, tagging the commit, pushing to GitHub, and crafting a tidy CHANGELOG.md. It’s boring, repetitive, and prone to mistakes. How can we fix that?

Enter Release-it — a CLI that helps automate version bumping, changelog generation, Git tagging, GitHub releases, and more. With a few lines of configuration you can turn those 15-minute “release chores” into a single command (or a CI step) you never think about again.

Setup

Prerequisites

Before starting there some mirror prerequisites:

Requirement Why it matters
Git repository Release-it tags and pushes via Git
Follow Conventional Commits Enables automatic changelog categorisation
Node ≥ 16 (LTS recommended) Required runtime for the CLI

Installation

Starting a fresh project? First, create a package.json:

Terminal window
npm init # creates package.json

Then, whether it’s a new or existing project, install the required dev dependencies:

Terminal window
npm install -D release-it @release-it/conventional-changelog

For convenience, add a script to package.json:

package.json
{
"scripts": {
"release": "release-it"
}
}

Now you can run the command npm run release to start the release process. On the first run, Release-it will be prompted to choose between embedding the configuration in package.json or a .release-it.json file.

This guide assumes the latter for clarity.

Configuration

Release-it’s configuration is powerful but flexible. Let’s walk through the basics and some advanced options.

Basic Configuration

Here’s a minimal configuration to get started:

.release-it.json
{
"$schema": "https://unpkg.com/release-it@19/schema/release-it.json",
"git": {
"commitMessage": "chore: release v${version}"
},
"github": {
"release": false // toggle true to create GitHub releases
},
"npm": {
"publish": false // set true for publishing libraries
}
}

Advanced Configuration Options

Git Configuration

{
"git": {
"commitMessage": "chore: release v${version}",
"tagName": "v${version}",
"tagAnnotation": "Release v${version}",
"push": true,
"requireUpstream": true,
"requireCleanWorkingDir": true,
"requireBranch": "main"
}
}

GitHub Configuration

{
"github": {
"release": true,
"releaseName": "Release v${version}",
"releaseNotes": null,
"draft": false,
"prerelease": false,
"tokenRef": "GITHUB_TOKEN"
}
}

NPM Configuration

{
"npm": {
"publish": true,
"publishPath": ".",
"access": "public",
"otp": null
}
}

Conventional Changelog Configuration

The @release-it/conventional-changelog plugin helps you maintain a standardized changelog based on your commit messages. Here’s how to configure it:

{
"plugins": {
"@release-it/conventional-changelog": {
"infile": "CHANGELOG.md",
"preset": {
"name": "conventionalcommits",
"types": [
{ "type": "feat", "section": "Features" },
{ "type": "fix", "section": "Bug Fixes" },
{ "type": "docs", "section": "Documentation" },
{ "type": "style", "section": "Styles" },
{ "type": "refactor", "section": "Code Refactoring" },
{ "type": "perf", "section": "Performance Improvements" },
{ "type": "test", "section": "Tests" },
{ "type": "build", "section": "Builds" },
{ "type": "ci", "section": "Continuous Integration" },
{ "type": "chore", "section": "Chores" },
{ "type": "revert", "section": "Reverts" }
]
}
}
}
}

Configuration Options

Commit Types and Sections

The plugin supports all standard Conventional Commits types:

Example Changelog Output

# Changelog
## [1.1.0] - 2024-05-05
### Features
- Add new authentication system
- Implement dark mode
### Bug Fixes
- Fix login form validation
- Resolve navigation issues
### Documentation
- Update API documentation
- Add setup instructions

Hooks: Automate Your Workflow

Hooks are powerful tools that let you run custom scripts at specific points in the release process. They follow the format [prefix]:[plugin]:[hook].

Hook Types

Common Hook Examples

{
"hooks": {
// Pre-release checks
"before:init": [
"npm run lint",
"npm test",
"npm run build"
],
// Version bump notifications
"after:bump": "echo 'Version bumped to ${version}'",
// Post-release tasks
"after:release": [
"echo 'Release ${version} completed'",
"npm run deploy"
],
// Git-specific hooks
"after:git:release": "echo 'Git tag v${version} created'",
// GitHub-specific hooks
"after:github:release": "echo 'GitHub release created'"
}
}

Available Variables in Hooks

You can use these variables in your hook commands:

Real-world Hook Examples

{
"hooks": {
// Run tests and build before release
"before:init": [
"npm run test:ci",
"npm run build"
],
// Update documentation after version bump
"after:bump": "npm run docs:update",
// Deploy to staging after release
"after:release": "npm run deploy:staging",
// Notify team on Slack
"after:github:release": "curl -X POST -H 'Content-type: application/json' --data '{\"text\":\"New release ${version} is out!\"}' $SLACK_WEBHOOK"
}
}

Dry run

You can preview the release process without modifying Git:

Terminal window
npx release-it --dry-run

Github Actions

You can automate releases using GitHub Actions, e.g. on merge into main.

name: Release-it
on:
pull_request:
types: [closed]
branches: [main]
permissions:
contents: write
jobs:
release:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Set git identity
run:
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
- run: npm install
- run: npm run release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Conclusion

Manual releases slime time and invite errors. With Release-it you:

So the next time you finish that sprint, forget the copy-paste routine and let Release-it do the boring stuff—while you start the next great feature.