Sun May 02 2021

Making a release toolkit - Part 1: Changelog

I own a handful of npm packages, and for a while now I've been wanting to automate my release process. I'm going to take a page from Swyx's blog and do some learning in public.

There are tons of ways to automate the release process, and tons of existing packages for it. It's a process I'm accustomed to at work, but I've never set it up from scratch so I wanted to do it myself and figure out a thing or two in the process. Learn along with me!

I've got a few requirements:

  • Publish when I merge to the main branch
  • Publish both a new npm version and a new GitHub release at the same time
  • Update the changelog
  • Do it without me having to think about it

When I'm dealing with something with a number of moving pieces, the first thing I do is break it down into small chunks. I'm going to need to coordinate npm, GitHub, CI pipelines, and scripts. What's the first thing I can get started on without worrying about the whole ball of wax? The changelog CLI package has caught my eye, let's start with that.


I want to run a command from the terminal that will either generate or update a CHANGELOG.md with some nice formatting. I'll probably end up using the commander and/or inquirer packages to manage the command line interface, but for now let's just get the minimum viable product up and running. The CLI MVP, if you will. I hope you will.

While I'm at it, Node is phasing out version 10, meaning all current versions of Node will be compatible with ES modules. Let's write this thing in import/export syntax and see how green that grass is.

Step 1: Get something super basic running and use it from one of my packages. I write a quick index.js where I hardcode some data and output a CHANGELOG.md file, looks good when I run it locally:

## [0.1.1](link-to-github-release-will-go-here) (2021-05-02)

**Bug fix**

- Fixed a buggo

## [0.1.0](link-to-github-release-will-go-here) (2021-05-02)

**Feature**

- Features galore

But when I try to run it from another project using npx helloitsjoe/changelog 1 I get an error: command not found: changelog 🤔

Where's that coming from? I'm not trying to run anything with a changelog command, that's just the name of the project... (gears turn, things slowly make sense) ...oh, it's using the package name as an executable. This is how commands like jest work. Why is the command not found though? I'm setting index.js as main in package.json... now that I think of it, I think there's a bin (binary) field in package.json for executing commands. Switch main to bin and... it works!

Now to clean it up a bit. Let's add inquirer for user input so I can add the type of change (Feature, Bug fix, etc) and a description. inquirer is a great package for this, makes it easy to do different kinds of CLI input (multiple choice, custom input using your editor of choice).

Multiple select using inquirer

I'll use git remote get-url origin to populate the link to the GitHub release, get the version from package.json and throw an error if a changelog exists for the current version. Good enough for the MVP!

Learnings:

  • If you want to make a package executable from the command line, use the bin field instead of main in package.json
  • So far no issues with ES modules, things seem pretty smooth

Couple of interesting things. I always like projects like this, where I'm filling in gaps in tooling I use all the time at work but haven't built from scratch before (in this case bin).

Now that I've scratched that itch, let me zoom out and take some TODO notes:

  • Rename repo from changelog to release-toolkit and add a few other scripts
    • version script bumps package.json
    • verify script checks changelog and version changed
    • publish script publishes to npm and GitHub at the new version
  • Set this up to run in a GitHub Action

Next up, let's write some tests!


1: You can install/run npm packages directly from GitHub repos