Fat Codes

Software engineering related ramblings by fat

Nodejs Microservices Release Script

At Apio, we take “not so smart objects” such as a meter, a switch, or any other kind of device, and we turn it into a super device, able to communicate through internet with our infrastructure and, eventually, join the “March of the Machines” against humanity.

Jokes aside, to turn anything like a meter measurement into actionable data (alerts, analytics, commands to other devices) we need to process data in several steps.

Our development team’s lingua franca is Javascript, and the vast majority of our microservices are HTTPS based NodeJS programs, often talking to a MongoDB database and to other peers microservices through HTTPS or Nats.

We are not a very large team at the moment, we surely have more microservices than members, so it’s very important to keep things small, separated, easy to understand, to fix and to operate. For this reason we encapsulate every piece of functionality into a nodejs microservice. To keep track of which version of a microservice is deployed in which environment we use npm version numbers: we set the microservice version number both as a git tag and as package.json version field, then our typical “GET /” route for every microservice would print something like:

{
"name": "Apio Analytics Service API",
"description": "This is the HTTPs api for interacting with Apio Analytics",
"version": "2.1.3"
}

In this way we can easily track which version is deployed where with a single HTTP request. A release version is useful for a number of reasons, some of which are:

  • Api versioning
  • Add information to Jaeger traces
  • Add version to sentry errors
  • Notify other team members that your service has some major changes so you increase the major version number (X.y.z)

Handling this version by hand can be tedious, and if you forget to do it, you lsot precious information. So I made this script that we are happily using for each of our nodejs project:

#!/bin/sh
# Increments the project version (e.g. from 2.3.0 to 2.4.0)
# It handles stuff like
# * CHANGELOG
# * NPM package version
# * Git tags
# Calculating the new version requires to know which kind of update this is
# The default version increment is patch
# Used values: major|minor|patch where in x.y.z :
# major=x
# minor=y
# patch=z
if [ -z "$1" ]
then
versionType="patch"
else
versionType=$1
fi
# Increment version without creating a tag and a commit (we will create them later)
npm --no-git-tag-version version $versionType || exit 1
# Using the package.json version
version="$(grep '"version"' package.json | cut -d'"' -f4)"
# Generate changelog from commits
rm CHANGELOG.md;
npx conventional-changelog -t -i CHANGELOG.md --same-file;
# Build the commit
git add package.json;
git add package-lock.json;
git add CHANGELOG.md;
# Remove the [skip ci] if your CI/CD env does not support it
git commit -m "📦 Release $version [skip ci]"
# Create an annotated tag
git tag -a $version -m "📦 Release $version"
# Gotta push them all
git push origin master --follow-tags;
view raw release.sh hosted with ❤ by GitHub