Automating releases via Semantic release

Kopal Gupta
Jul 1, 2020 · 4 min read

Releases are the essence of a software project. When it comes to releases we need to know when it has happened and what it includes? So, it’s common to keep a change log and tags for releases, but who has time for that when you have to Ship Early, Ship Often?

At MiQ, we want our releases to be automated and streamlined. As an important procedure the following steps were on our mind:

  • Follow semantic versioning in order to distinguish between feature releases, bug fixes, and breaking changes.
  • Generate release notes/changelog in an automated manner so that other developers working with us can understand what are the changes included in every release and their implications.
  • Ditch the manual process of determining the next incremental version and creating release notes which may be time-consuming, error-prone, and repetitive.
  • Automatically generate a git tag and commit release assets to the Project’s git repository.

How we solved it?

Meet Semantic Release, It’s an Open-Source Node.js command-line tool, that automates the whole project release workflow including incremental generation of the version number, generating the release notes, publishing the package, and generating the git tag.

How does it work?

  1. Semantic-release runs on a CI server(Jenkins in our case).
  2. After each successful build, it analyzes new commits and checks if there’s something to publish.
  3. Determines the release type (PATCH, MINOR, or MAJOR) by analyzing commit messages (using a commit-analyzer plugin).
  4. It then generates a changelog: Based on your release type (PATCH, MINOR, or MAJOR) from commit messages.
  5. Finally, it publishes a changelog to the Git repository using a git plugin and also creates release and the semantically correct version tag for that release.
An image depicting semantic versioning.

TL;DR: Let’s jump straight into the configuration:

What do we need to do?

To be confident enough that a correct version has been released, we need our commits to follow a standard. In our case, we use Conventional commits.

Conventional commits are a specification for formatting commit messages that’s lightweight and readable by both humans and machines.

A diagram that explains the different parts of the conventional commit message.

How do we make sure that each member of the team writes conventional commit messages?

To battle this, there is a plugin called Commitizen. It helps to write the conventional commit message. Using Commitizenscz-cli couldn’t be simpler: just replace git commit command with git cz and you’ll be prompted to fill out any required fields at commit time. That’s it, really!

How to implement this?

  • First, we need to install semantic-release and the plugins we intend to use based on our configuration, follow this for the available plugins and their usage.
npm i -D semantic-release @semantic-release/{git,commit-analyzer,release-notes-generator,npm,changelog}
  • Next, we can see the documentation here to configure semantic release based on our needs. (An example of how to configure releaserc.json for this is shown below).
An example of a configuration file for Semantic release
  • We now need to generate a token (BB_TOKEN in case of Bitbucket or GH_TOKEN in case of Github) i.e. personal access token of our repository and include it in Jenkins as an environment variable, post all these steps we can now create a Jenkins Job and finally do the release in an automated manner by running the command npx semantic-releaseor specifying the same in the Jenkinsfile. Rest all the CI takes care!

We also use the git workflow with semantic release:

The workflow we use here in MiQ is shown in the following image.

A diagram that explains the Git workflow with Semantic Release

Is that all we have to do to automate releases?

Yes! that’s all we have to do to automate the releases of our Project. But, often the setup and configuration can be complicated. So, here’s a tip for you i.e. you can also run semantic-release in no-ci and dry-run mode to see the changelog and the whole process in a local terminal before rolling out the final release. By running the command(check the docs here),

npx semantic-release --dry-run --no-ci

You may now implement the same and have your project semantically released.

MiQ Tech and Analytics

MiQ Tech and Analytics Blog