Contents

Semantic Versioning

What exactly am I about to take to production?

Background

If you’ve written software for any length of time, you may have found yourself asking a question, the question that haunts and stalks you when you take a release candidate to production.

What exactly am I about to take to production?

As Software Engineers, we know about semantic versioning, and most of us know about CHANGELOG files, but I’ve recently been tinkering with automating these, to some positive outcomes.

The Problem

  • A merge from develop to master will trigger pipelines to run that will test a production candidate and then deploy this code to production.
  • The diff between develop and master will contain the changes between the candidate production release and the current production code.
  • develop branch should represent a stable test environment, and doesn’t need versioning.
  • master branch gets deployed to production, and does need versioning, as well as a list of changes that have contributed towards each version.
  • master branch should follow semantic versioning standards, and ideally versions should be free from sentiment–if the code has taken a breaking change, for example, the major version number should be incremented.

A Solution

@semantic-release can be leveraged for NodeJS packages (there’s also a Maven plugin, but I’ve not yet worked with it), along with several plugins.

In order to bump NodeJS packages, the package.json file needs to include some configuration (a standalone file can be used, but I have a strong preference towards using package.json to configure this plugin and track the package version).

{
  "version": "1.0.0",
  "private": true,
  "plugins": [
    "@semantic-release/commit-analyzer",
    "@semantic-release/release-notes-generator",
    ["@semantic-release/npm", {
      "npmPublish": false,
      "pkgRoot": "./src"
    }],
    ["@semantic-release/git", {
      "assets": ["package.json", "package-lock.json"]
    }]
  ]
}

Typically, I set up a job called versioning in my pipeline, trigger on changes to master branch, and run the following commands there:

npm i @semantic-release/commit-analyzer @semantic-release/release-notes-generator @semantic-release/npm @semantic-release/gitlab -g
git fetch --tags -f
npx semantic-release@19

Result

  1. Tags will be created in the GitLab repository containing the product.
  2. Releases will be created in the GitLab repository containing the product.
  3. Releases will be backed by a CHANGELOG document that is created by replaying and parsing commit messages on the branch.
    • Commit messages will need to fit a particular format; I like to use the Angular commit format, and show its badge https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release in my CONTRIBUTORS or README file.
  4. master branch will contain a package.json file with the updated version identifier, built from the formatted commit messages parsed by semantic release.