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:
main branchnpm version and a new GitHub release at the same timeWhen 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).

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
binfield instead ofmaininpackage.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:
changelog to release-toolkit and add a few other scriptsversion script bumps package.jsonverify script checks changelog and version changedpublish script publishes to npm and GitHub at the new versionNext up, let's write some tests!
1:
You can install/run npm packages
directly from GitHub repos