CLI release tool for Git repos and npm packages.
Release It! automates the tedious tasks of software releases:
- Execute test & build commands
- Bump version (in e.g.
package.json
) - Generate changelog
- Git commit, tag, push
- Publish to npm
- Create release at GitHub
- Upload assets to GitHub release
- Manage pre-releases
- Support Conventional Changelog workflows
- Support monorepo workflows
See CHANGELOG.md for major updates and breaking changes. Refer to the releases section for a detailed version history. Want to help out, or hack on release-it? Great! Please read CONTRIBUTING.md on how to participate.
Table of Contents (click to expand)
As a globally available CLI command:
npm install --global release-it
As a devDependency
in your project:
npm install --save-dev release-it
Add this as a script
to package.json
:
{
"name": "my-package",
"version": "1.0.0",
"scripts": {
"release": "release-it"
},
"devDependencies": {
"release-it": "*"
}
}
Now you can run npm run release
from the command line.
Release a new version:
release-it
You will be prompted to select the new version. To skip the first prompt, provide a specific increment or version:
release-it minor
release-it 0.8.3
For versions like 1.0.0-beta.2
and npm tags, see manage pre-releases.
For a "dry run", to show the interactivity and the commands it would execute:
release-it --dry-run
Out of the box, release-it has sane defaults, and plenty of options to configure it. Put the options to override in .release-it.json
in the project root. Example:
{
"git": {
"tagName": "v${version}"
},
"github": {
"release": true
}
}
Or in a release-it
property in package.json
:
{
"name": "my-package",
"devDependencies": {
"release-it": "*"
},
"release-it": {
"github": {
"release": true
}
}
}
Notes:
- Only the settings to override need to be in
.release-it.json
(orpackage.json
). Everything else will fall back to the default configuration. - You can use
--config
if you want to use another path for.release-it.json
.
Any option can also be set on the command-line, and will have highest priority. Example:
release-it minor --git.tagName='v${version}' --github.release
Boolean arguments can be negated by using the no-
prefix:
release-it --no-npm.publish
By default, release-it is interactive and allows you to confirm each task before execution:
By using the -n
option (i.e. non-interactive), the process is fully automated without prompts. The configured tasks will be executed as demonstrated in the first animation above.
On a Continuous Integration (CI) environment, the non-interactive mode is activated automatically.
An overview of the tasks (click to expand)
Task | Option | Default | Prompt | Default |
---|---|---|---|---|
Git commit | git.commit |
true |
prompt.commit |
Y |
Git tag | git.tag |
true |
prompt.tag |
Y |
Git push | git.push |
true |
prompt.push |
Y |
GitHub release | github.release |
false |
prompt.release |
Y |
npm publish | npm.publish |
true |
prompt.publish |
Y |
The Option/Default columns represent default options in non-interactive/CI mode. The Prompt/Default columns represent the prompts and their default answers in interactive mode. You can still change the answer to either Y
or N
as the questions show up (or cancel the process with Ctrl-c
).
If an option is set to false
, the related prompt will not be shown at all in interactive mode (regardless of its default answer).
By default, release-it uses the latest Git tag to determine which version should be released.
For projects that don't have a Git tag (yet), or if the Git tag isn't a valid semver, it falls back to the version
found in package.json
. As a last resort, 0.0.0
will be used as the latest version.
To explicitly use the version
from package.json
as latest version, set "use": "pkg.version"
(or --use=pkg.version
).
In case the repo itself should not be tagged, make sure to set git.tag
to false
.
This is also useful for monorepos.
SSH keys and Git remotes are assumed to be configured correctly. If a manual git push
from the command line works, release-it should be able to do the same.
The following GitHub help pages might be useful: SSH and Managing Remotes.
By default, release-it
uses origin
as the remote name to push to. Use git.pushRepo
to override this with a different remote name (or a different git url).
In case extra arguments should be provided to Git, these options are available:
git.commitArgs
git.tagArgs
git.pushArgs
For example, use "git.commitArgs": "-S"
to sign commits (also see #35).
By default, untracked files are not added to the release commit. Use git.addUntrackedFiles: true
to override this behavior.
The "Releases" tab on GitHub projects links to a page to store the changelog. To add GitHub releases in your release-it flow:
- Configure
github.release: true
. - Obtain a GitHub access token (release-it only needs "repo" access; no "admin" or other scopes).
- Make sure the token is available as an environment variable. Example:
export GITHUB_TOKEN="f941e0..."
Do not put the actual token in the release-it configuration. It will be read from the GITHUB_TOKEN
environment variable. You can change this variable name by setting the github.tokenRef
option to something else.
Obviously, release-it uses this feature extensively: release-it's releases page.
By default, the output of scripts.changelog
is used for the GitHub release notes. This is the printed Changelog: ...
when release-it boots.
Override this with the github.releaseNotes
option. This script will run just before the actual GitHub release itself.
Make sure it outputs to stdout
. An example:
{
"github": {
"release": true,
"releaseNotes": "generate-release-notes.sh ${latestVersion} ${version}"
}
}
To upload binary release assets with a GitHub release (such as compiled executables, minified scripts, documentation), provide one or more glob patterns for the github.assets
option. After the release, the assets are available to download from the GitHub release page. Example:
{
"github": {
"release": true,
"assets": ["dist/*.zip"]
}
}
No configuration is needed to publish the package to npm, as npm.publish
is true
by default. If a manual npm publish
from the command line works, release-it delegating to npm-publish
should behave the same. The "private": true
setting in package.json will be respected, and release-it
will skip this step.
Getting an ENEEDAUTH
error while a manual npm publish
works? Please see #95.
Set npm.access
to "public"
to publish scoped packages, or make sure this is in package.json
:
{
"publishConfig": {
"access": "public"
}
}
In case two-factor authentication (2FA) is enabled for the package, release-it will ask for the one-time password (OTP).
The OTP can be provided from the command line (--npm.otp=123456
). However, providing the OTP without a prompt basically defeats the purpose of 2FA (also, the OTP expires after a short period).
With release-it, it's easy to create pre-releases: a version of your software that you want to make available, while it's not in the stable semver range yet. Often "alpha", "beta", and "rc" (release candidate) are used as identifier for pre-releases.
An example. The awesome-pkg
is at version 1.3.0, and work is done for a new major update. To publish the latest beta of the new major version:
release-it major --preRelease=beta
This will tag and release version 2.0.0-beta.0
. Notes:
- A normal installation of
awesome-pkg
will still be at version 1.3.0. - The npm tag will be "beta", install it using
npm install awesome-pkg@beta
- A GitHub release will be marked as a "Pre-release".
The above command is actually a shortcut for:
release-it premajor --preReleaseId=beta --npm.tag=beta --github.preRelease
Consecutive beta releases (2.0.0-beta.1
and so on):
release-it --preRelease
And when ready to release the next phase (e.g. release candidate):
release-it --preRelease=rc
And eventually, for 2.0.0
:
release-it major
Notes:
- Pre-releases can work together with recommended bumps.
- You can still override individual options (e.g.
release-it --preRelease=rc --npm.tag=next
). - See semver.org for more details about semantic versioning.
These script hooks can be used to execute commands (from the root directory of the repository):
scripts.beforeStart
scripts.beforeBump
scripts.afterBump
scripts.beforeStage
scripts.afterRelease
All commands can use configuration variables (like template strings). Some examples:
{
"scripts": {
"beforeStart": "npm test",
"afterBump": "tar -czvf foo-${version}.tar.gz",
"afterRelease": "echo Successfully released ${name} v${version} to ${repo.repository}."
}
}
The variables can be found in the default configuration. Additionally, the following variables are exposed:
version
latestVersion
changelog
name
repo.remote, repo.protocol, repo.host, repo.owner, repo.repository, repo.project
For distribution repositories, two additional hooks are available:
dist.scripts.beforeStage
dist.scripts.afterRelease
From a monorepo package subdirectory, release-it detects package.json
is not in the same directory as the Git root.
Then it will take the latest version from this package.json
rather than the latest Git tag.
To not tag the monorepo itself, set git.tag
to false
. For example, from ./packages/some-pkg
:
release-it --git.commitMessage='Release ${name} v${version}' --no-git.tag
If your project follows conventions, such as the Angular commit guidelines, the special conventional:angular
increment shorthand can be used to get the recommended bump based on the commit messages:
{
"increment": "conventional:angular"
}
Please find the list of available conventions (angular
, ember
, etc).
With release-it, you can use tools like conventional-changelog-cli to generate the changelog. Make sure the command defined in scripts.changelog
outputs the changelog to stdout
. In the next example, scripts.beforeStage
is also used, to update the CHANGELOG.md
file (and include this change in the release commit).
{
"increment": "conventional:angular",
"scripts": {
"changelog": "conventional-changelog -p angular | tail -n +3",
"beforeStage": "conventional-changelog -p angular -i CHANGELOG.md -s"
}
}
Some projects use a distribution repository. Generated files (such as compiled assets or documentation) can be distributed to a separate repository. Or to a separate branch, such as a gh-pages
(also see Using GitHub Pages, the easy way). Some examples include shim repositories and a separate packaged Angular.js repository for distribution on npm and Bower.
To use this feature, set the dist.repo
option to a git endpoint.
An example configuration (click to expand)
{
"scripts": {
"beforeStage": "npm run build"
},
"dist": {
"repo": "git@github.com:components/ember.git",
"stageDir": ".stage",
"baseDir": "dist",
"files": ["**/*"],
"github": {
"release": true
},
"npm": {
"publish": true
}
}
}
With this example:
- The
dist.repo
will be cloned to.stage
. - From the root of source repo,
npm run build
is executed. - The generated files at
dist/**.*
will be copied to the.stage
directory. - The result is pushed back to
dist.repo
. - A GitHub release is created, and the package is published to npm.
Use --disable-metrics
to opt-out of sending some anonymous statistical data to Google Analytics.
For details, refer to lib/metrics.js.
Please consider to not opt-out: more data means more more support for future development.
- Use
--verbose
to output commands that release-it executes. - Use
--debug
to output configuration and additional (error) logs. - Use
DEBUG=octokit:rest* release-it [...]
for debug logs with GitHub releases & assets.
From Node.js scripts, release-it can also be used as a dependency:
const releaseIt = require('release-it');
releaseIt(options).then(output => {
console.log(output);
// { version, latestVersion, changelog }
});
- react-navigation/react-navigation
- swagger-api/swagger-ui
- StevenBlack/hosts
- react-native-community/react-native-tab-view
- callstack/linaria
- vuejs/vuefire
- posva/vue-promised
- blockchain/blockchain-wallet-v4-frontend
- infor-design/enterprise
- tsqllint/tsqllint
- segmentio/typewriter
- Repositories that depend on release-it
- GitHub search for projects with .release-it.json
- semver.org
- GitHub Help (→ About Releases)
- npm Blog: Publishing what you mean to publish
- npm Documentation: package.json
- Prereleases and npm
- Glob Primer (node-glob) (release-it uses globby)
Major dependencies:
The following Grunt plugins have been a source of inspiration: