Automated versioning and publishing of npm workspace projects
Table of Contents:
release-workspaces brings the power of Release It! to monorepos. All built with npm workspaces in mind. Using this utility, you can do the following:
- Version packages
- Publish packages
- Commit, tag, and push to remote
- And More*!
*See roadmap
One of the key benefits of npm workspaces is running commands across packages, and managing inter-package dependencies. However, like non-workspace projects, versioning and publishing is more or less a very manual process.
It's therefore not in the perview of this package to interact with behavior beyond versioning and publishing.
This tool assumes a few things about your workflow:
- You're logged into NPM from your terminal environment
- You're using npm workspaces (npm 7.x)
- All your packages will use the same version for each release
release-workspaces is used primarily as a command line integration tool combined with an optional configuration file.
The basic requirement is to have a version field defined in your root package.json (you can alternatively add metadata.version to your config file). This will be the version of your packages, and is automatically updated for you after a release succeeds.
Using the tool can be as simple as this:
$ release-workspaces --increment major
# or
$ release-workspaces -i majorWith only a version field in your root package.json, mind you!
Here's a more complex example of incrementing packages from prerelease, to release candidate, to minor version.
$ release-workspaces -i preminor --preid alpha # 0.1.0 -> 0.2.0-alpha.0
$ release-workspaces -i prerelease # 0.2.0-alpha.1
$ release-workspaces -i prerelease --preid rc --npm-tag next # 0.2.0-rc.0 @ next
$ release-workspaces -i minor # 0.2.0While the tool runs with sensible defaults, you can create a configuration of your own to customize execution.
Define the config in one of two ways:
.release-workspaces.jsonfile in monorepo root"release-workspaces"field of package.json
Basic data about your project.
Defaults:
{
"metadata": {
"version": ""
}
}Configures how to run npm operations (increment version & publish).
Defaults:
{
"npm": {
"increment": true,
"publish": true
}
}NOTE: Setting both increment and publish to false is a valid configuration if you only wish to tag the latest commit.
Configures how to run git operations (commit, tag, push). Use ${version} in string values to insert the new version when processed.
Defaults:
{
"git": {
"requireCleanDir": true,
"requireSync": true,
"skipChecks": false,
"commitMessage": "Release ${version}",
"tagMessage": "Release ${version}",
"commit": true,
"tag": true,
"push": true
}
}Configures the tool to run scripts during the execution lifecycle. If you need to run an npm lifecycle script such as preversion or prepublishOnly, define them in the individual package's package.json to have them trigger automatically at the corresponding step.
Available hooks:
preincrement,postincrement: Runs before/after packages are versionedprepublish,postpublish: Runs before/after packages are publishedprecommit,postcommit: Runs before/after publish artifacts are committedpretag,posttag: Runs before/after a release tag is generatedprepush,postpush: Runs before/after the commit is pushed to the remote (does not run if bothconfig.git.commitandconfig.git.tagare false)
Arguments passed through the CLI will be passed verbatim to and validated by semver under the hood.
| Name | Type | Description |
|---|---|---|
--increment, -i |
string | The release increment. E.g. minor, prepatch, prerelease, etc. |
--increment-to, -s |
string | A specific version to publish. E.g., 3.0.0, 3.0.0-rc.2, etc. |
--preid, -p |
string | Sets the prerelease id. E.g. alpha, rc, etc. |
--npm-tag, -n |
string | If given, sets the npm publish tag. Otherwise uses the preid. E.g. next. |
--dry-run, -d |
boolean | Prints normal output but doesn't execute. |
--verbose, -b |
boolean | Prints all commands and mutating script calls (can be used with --dry-run/-d). |
Note that if --npm-tag isn't given, then the tool will fall back to the value given for --preid, else it will use latest.
Similarly, if you run a git-only release (no version, no publish), the tool will fall back to the current version of your packages.
Using config options via CLI will override your config. Useful for one-off releases and otherwise augmenting a base configuration for release types (alpha release, release candidate, no-increment publish, etc).
You can use any of the existing config options as CLI flags by using the formula --<key>.<property> [value]. E.g., change the default or user-configured commit message: --git.commitMessage "chore: release \${version}" or disable all git checks with --git.skipChecks.
Similarly, you can negate any boolean option by prepending --no- to it. E.g., --no-git.requireCleanDir.
Here are a few handy examples of how to achieve certain release results with CLI flags. Replace minor with your intended release increment.
| Description | Example |
|---|---|
| Do everything | $ release-workspaces -i minor |
| Prerelease | $ release-workspaces -i preminor -p alpha |
| Increment prerelease | $ release-workspaces -i prerelease |
| Update prerelease id w/ npm tag | $ release-workspaces -i prerelease -p rc -n next |
| Increment to a specific version | $ release-workspaces -s 3.0.0 |
| Skip npm version | $ release-workspaces --no-npm.increment |
| Skip npm publish | $ release-workspaces -i minor --no-npm.publish |
| Skip all npm operations | $ release-workspaces --no-npm.increment --no-npm.publish |
| Skip clean directory check | $ release-workspaces -i minor --no-git.requireCleanDir |
| Skip git sync check | $ release-workspaces -i minor --no-git.requireSync |
| Skip all git checks | $ release-workspaces -i minor --git.skipChecks |
| Skip git operation | $ release-workspaces -i minor --no-git.[commit/tag/push] |
| Set custom messaging | $ release-workspaces -i minor --git.[commitMessage/tagMessage] "Custom msg for \${version}" |
There are some contradictory or otherwise unclear config combinations to note.
config.git.pushis ignored if bothconfig.git.commitandconfig.git.tagarefalse.--increment-to/-sis ignored ifconfig.npm.incrementisfalse.--increment-to/-swill override--increment/-i.--increment-to/-s, if valid version, will automatically be parsed for an npm tag during the publish step. You can optionally provide--npm-tagto override this.
- Rollback changes if failures occur mid-release
- Automate GitHub/GitLab releases
- Release in CI
