Nice and easy module releases

Generate a changelog as part of the npm version command

Maximilian Antoni
JavaScript Studio

--

Photo by SpaceX

I like building small, focused modules which get released frequently, often multiple times per day. Therefore it’s critical for me to have a release process that makes me feel confident and is highly automated. I use npm as a build tool, so every module ships with all the development tools required to lint the code and run the tests using npm scripts. When I started building the first couple of modules for the JavaScript Studio project, I wanted the release process to fit into this model.

Many module authors already use npm version to prepare their releases. For example, when you run npm version minor, npm will bump the minor version in the package.json file and create a version commit with the new version number as the commit message. Using npm is a natural fit for my needs, but I want to write release notes based on the commit history and added to the release commit. This is exactly what the@studio/changes module allows me to do.

How does it work?

You can add the changes module to your release process in two steps:

  1. npm install @studio/changes --save-dev
  2. Add a version script to your package.json which simply calls changes (npm makes it available on the PATH already).

That’s it! Now just run npm version [patch|minor|major] and your default text editor will open either with your existing, or a new CHANGES.md file. It will have a new heading with the version number and a list of changes, populated from your commit log as a starting point. Once you finished editing the release notes, simply save and close the editor and the CHANGES.md file will be added to the version commit.

More automation!

The npm version command calls the following scripts:

  • preversion is called before the package.json file has been changed. We can use this to run npm test, so that the release process is aborted if the tests don’t pass. Note that this will also trigger any pretest or posttest scripts which you can use to run a linter.
  • version is called right after the package.json file has been changed, but before npm creates the commit.
  • postversion is called after the commit. To fully automate the release process, you can even run git push --follow-tags && npm publish here.

This is what it looks like all together:

"scripts": {
"preversion": "npm test",
"version": "changes",
"postversion": "git push --follow-tags && npm publish"
},
"devDependencies": {
"@studio/changes": "^1.0.0"
}

Pushing and publishing in the postversion script might seem quite radical, but here’s the thing: When your editor opens with the CHANGES.md file, it acts as a confirmation, like editing a git commit message. If you want to abort the release, simply remove the line with the version heading. The changes script will exit with a non-zero exit code, causing npm to abort the release.

Now, the only command you need to remember to do a release is npm version and everything else happens automagically. Needless to say that @studio/changes is released this way with itself 🤓

I’d love to hear your thoughts! If you like this approach, pop by the GitHub repository and leave a ⭐️

More changelog tools

  • There is changelog, which operates on any given npm module or a github repository, should the changelog be missing 🙊, or if you need a special format.
  • If you’re into 100% automated releasing, check out semantic-release.

Thanks for reading!

--

--

Maximilian Antoni
JavaScript Studio

Node & web frontend engineer. Working on JavaScript Studio.