The more an NPM library becomes "stable", the more publishing a new version of it on NPM becomes quite a boring task:
- Someone sends a PR for a small bugfix/improvement
- The PR gets reviewed and merged
- The library version number gets bumped and released
- Someone writes the changelog
Enter semantic-release
, a powerful set of tools for fully automating version management and package publishing.
With semantic-release
you can easily automate the flow described above by letting it handle for you the release process in your Continuous Integration.
First, install semantic-release
:
npm install --save-dev semantic-release
npm install --save-dev semantic-release
The semantic-release
package has almost everything you need... but to get the most of it you'll also need an additional plugin (that for some reason is not included by default):
npm install --save-dev @semantic-release/git
npm install --save-dev @semantic-release/git
Next step, create the semantic-release
configuration file, which is a JSON file name .releaserc
file at the root of you project:
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/npm",
"@semantic-release/github",
"@semantic-release/git"
]
}
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/npm",
"@semantic-release/github",
"@semantic-release/git"
]
}
Let's now move to the CI setup.
In my case I'm using CircleCI, but semantic-release
is unopinionated on this subject.
Create (or update) a .circle/config.yml
file for running semantic-release
after your tests:
# Example config
version: 2
jobs:
test:
docker:
- image: circleci/node:10
steps:
- checkout
- run: npm install
- run: npm test
release:
docker:
- image: circleci/node:10
steps:
- checkout
- run: npm install
- run: npx semantic-release
workflows:
version: 2
test_and_release:
# Run the test jobs first, then the release only when all the test jobs are successful
jobs:
- test
- release:
requires:
- test
# Example config
version: 2
jobs:
test:
docker:
- image: circleci/node:10
steps:
- checkout
- run: npm install
- run: npm test
release:
docker:
- image: circleci/node:10
steps:
- checkout
- run: npm install
- run: npx semantic-release
workflows:
version: 2
test_and_release:
# Run the test jobs first, then the release only when all the test jobs are successful
jobs:
- test
- release:
requires:
- test
semantic-release
requires two environment variables to run:
GH_TOKEN
: An NPM token NPM token create.NPM_TOKEN
: GitHub personal authentication token.
Now, whenever a new PR gets merged in your master
branch your CI runs the tests and, if they succesfull, it runs the semantic-release
process, which:
- Checks the commit message (
@semantic-release/commit-analyzer
):semantic-release
determines how to bump the library version (major/minor/patch, following the semver) based on the commit messages used in the merged PR. This means that when merging a PR you should make sure it follows the Angular Comment Message Convention, which is the default convention used bysemantic-release
. - Creates a changelog (
@semantic-release/release-notes-generator
): based on the commit messages above,semantic-release
generates a changelog. - Bumps and publish the new version on NPM (
@semantic-release/npm
):semantic-release
bumps the version number of the library and publishes it on NPM (thanks to theNPM_TOKEN
env var) - Publish the release on GitHub (
@semantic-release/github
):semantic-release
publishes on GitHub a new release with the changelog that was previously generated - Commit the bumped package version (
@semantic-release/git
):semantic-release
commits on the repo the changes generated in the CI (the most important one is thepackage.json
version bump)
That's it!
I tried to keep this post as short as possible, you can find more information in the semantic-release GitBook.