Releases with Semantic-release

Posted on 3. May 2020 - 2 min read

I have been writing a coupe of NPM packages recently and publishing those NPM packages was quite manual and repetitive. If bumping versions, changelog and Github releases are included, the amount of manual work will cost plenty of time. It could easily take up to 30 minutes to have a nicely published NPM package. I then googled the problem and found sementic-release. The tool is very handy and it also provides a bunch of cool features due to its plugins system.

semantic-release supports CI workflow as well as local workflow. The following would give you some ideas how I used it via local workflow.

Installation

In order to start using semantic-release, you will need to setup both NPM token as well as Github token as environment variables. I store them in one of my dotfiles for convenience. An example of my .localrc:

export GH_TOKEN=someveryrandomgithubtoken
export NPM_TOKEN=anothersuperrandomnpmtoken

If you not sure how to generate those tokens, semantic-release-cli can help to generate them in few minutes and initialize configurations for a project. I used it in my first project to get tokens and be familiar with the tool. I then no longer use it as it keeps asking passwords and MFA token:

yarn global add semantic-release-cli
semantic-release-cli setup

semantic-release-cli basically adds semantic-release as a development dependency and a couple of configs to package.json.

If GH_TOKEN and NPM_TOKEN are configured, it might be faster to add semantic-release manually:

npm install --save-dev semantic-release

I updated scripts in package.json for convenience:

{
  "scripts": {
    "release": "semantic-release"
  }
}

Configurations

I use release.config.js for storing configurations. By default, the configuration should be like this:

module.exports = {
  "plugins": [
    '@semantic-release/commit-analyzer',
    '@semantic-release/release-notes-generator',
    '@semantic-release/npm',
    '@semantic-release/github',
  ]
}

With the default configurations, semantic-release will analyze commits using Angular conventions to generate release notes. It then publishes to NPM repository and publishes a new release in Github. It also update package.json for the new package version but commit it. Therefore, an additional plugin is required.

As I want to generate CHANGELOG and commit the changed version in package.json automatically, I added two more plugins:

yarn add -D @semantic-release/changelog @semantic-release/git

and in release.config.js:

module.exports = {
  "plugins": [
    '@semantic-release/commit-analyzer',
    '@semantic-release/release-notes-generator',
    '@semantic-release/changelog',
    '@semantic-release/npm',
    '@semantic-release/github',
    '@semantic-release/git',
  ]
}

The two new plugins will generate CHANGELOG.md and push it together with package.json to github. You can read more about them in:

Release

Release is super simple. After committing your changes with the repository, you can run:

yarn release -d

to review your release notes. After verifying, you can use the following command to publish:

yarn release --no-ci

Then a new version of your package will be published to NPM and Github.

CI

I didn't set up a CI as one-command release is more than enough for me. If you want to get of your hands free, you can try with Github Actions via this document.