DEV Community

Gregor Martynus
Gregor Martynus

Posted on

Automate npm releases using semantic-release

In an ideal world, the source code of an npm library is in sync with the versions published to the npm registry.

The problem is that the latest package versions published to npm are lacking behind their code. This results in

  1. Frustrated contributors, whose pull requests got merged and now wait to use the new version that includes their fixes or features
  2. Confused users that run into a bug that is marked as resolved on GitHub
  3. Stressed maintainers that are pressured by comments such as "When will this fix be released?" on closed issues and pull requests.

The solution: automation. Enter semantic-release

In a nutshell, semantic-release relies on commit message conventions to calculate and publish a new version of your package. By default, the 3 conventions are

  1. fix: ... prefix in commit subject: triggers a fix release version, e.g. 1.2.31.2.4
  2. feat: ... prefix in commit subject: triggers a feature version, e.g. 1.2.31.3.0
  3. BREAKING CHANGE: in commit body: triggers breaking version release, e.g. 1.2.32.0.0

That is all you need to learn.

Based on these conventions, new versions are continuously published to npm. Your code on GitHub and published versions on npm will never be out of sync again.

But semantic-release does much more than this:

  1. It creates GitHub releases to mirror the versions published to npm and adds changelogs based on above conventions and adds them to the GitHub releases. GitHub release
  2. It notifies contributors with comments in pull requests and resolved issues that a new version has been released Comment by semantic-release
  3. It lets you control in a single place who can both merge changes into the master branch and publish new versions to npm.

Setup using GitHub Actions

semantic-release supports a variety of CI providers, git hosts and package registries. For this example, I'll use GitHub Actions to publish to npm.

Install semantic-release

npm install --save-dev semantic-release
Enter fullscreen mode Exit fullscreen mode

If this is an existing project, make sure to create a git tag that matches the last version in the npm registiry, using a v prefix. For example, if the last version published to npm is 2.0.4, create a v2.0.4 tag and push it to your repository.

git tag v2.0.4
git push --tags
Enter fullscreen mode Exit fullscreen mode

No need to create a tag for new packages that have not yet been published.

Next, replace the version in your package.json file with "0.0.0-development". The version will be updated automatically by semantic-release. You no longer need to worry about it.

Next, create an npm token for your account at https://www.npmjs.com/settings/[YOUR USERNAME]/tokens with the read and publish setting. Copy that token and store it in your repository's secrets using the name NPM_TOKEN.

Finally, create a .github/workflows/release.yml file to run semantic-release each time a change is pushed to your repository's master branch.

name: Release
on:
  push:
    branches:
      - master

jobs:
  release:
    name: release
    runs-on: ubuntu-latest
    steps:
      # check out repository code and setup node
      - uses: actions/checkout@v1
      - uses: actions/setup-node@v1
        with:
          node-version: "12.x"
      # install dependencies and run semantic-release
      - run: npm ci
      - run: npx semantic-release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
Enter fullscreen mode Exit fullscreen mode

That's it. Next time you merge a pull request with commit messages following the conventions mentioned above, semantic-release will create the npm and GitHub releases as well as comments on the pull request and linked issues.

Closing words

You can see semantic-release in action all over my projects on GitHub. I usually make multiple releases each work day. I don't even think about it any longer. It frees up my time and thoughts to focus on the code instead of the chores around it.

And lastly, a tip: automating releases goes hand-in-hand with automating dependency updates. Services such as Greenkeeper even follow the required commit conventions when they send their pull requests. Merging the PRs is all it takes to release a new version. I highly recommend to use them both!

Top comments (2)

Collapse
 
mateiadrielrafael profile image
Matei Adriel • Edited

One of the best articles I read in the last few days!!!

Collapse
 
gr2m profile image
Gregor Martynus

Thanks Matei for the kind words, it means a lot :) Let me know if there is anything else you'd be interested in learning that I know a thing or two about. I'm still figuring out this writing thing