Automate changelog generation with standard-version

Mar. 12, 2022

Hello, it’s been a while.

Lately, I’ve been researching and learning more about changelogs because I’m collaborating on a changelog template with another member in the Community docs working group. We plan to start with a changelog template and then develop a release notes template in the future.

I’ve learned that changelogs generally:

Now imagine that you’re a maintainer on an open-source project, and you’re getting ready to release version 3.1.2 of your project. There are 20 commits on 3.1.2-staging that you want to merge into your release branch. Documenting each change by hand would be extremely tedious, especially if you don’t use a standard convention for writing commits. On top of that, you’d need to find commit links and include them in your changelog.

Rather than doing that all by hand, you can use a tool called standard-version to generate a changelog for you, bump the version of your software, and create a new tag for you.

Prerequisites

Step 1 – Install standard-version

First, open your repository in your code editor of choice.

To install standard-version as a local npm run script, run this command in the terminal:

npm i --save-dev standard-version

This command adds standard-version to the devDependencies property in your package.json file:

{
    "devDependencies": {
        "standard-version": "^9.3.2"
    }
}

After that, open your package.json file and create a new script command:

{
    "scripts": {
       "release": "standard-version"
    }
}

Now you can run standard-version using the command npm run release.

Step 2 – Create a .versionrc file

standard-version records commits that follow the conventional commits standard. If your commit message doesn’t follow the standard, it won’t be included in your changelog.

Commit messages that follow the standard usually look like this:

<type>[optional scope]: <description>

[optional body]

[optional footer]

By default, standard-version looks for commits with the type feat or fix. feat is typically used for new features, while fix is used for bug fixes. However, feat and fix aren’t the only types of commits you’ll make. Maybe you refactor some code, update a topic in your documentation, or update a unit test in your codebase.

You can customize standard-version to fit your project’s requirements by creating a .versionrc file in the root of your repository. In this file, you list the commit types you want to use, whether they should appear in the changelog, and what the section title for those types should be.

After you create the .versionrc file, add this configuration spec:

"types": [
    {"type": "feat", "section": "Added"},
    {"type": "fix", "section": "Fixed"},
    {"type": "change", "section": "Changed"},
    {"type": "chore", "hidden": true},
    {"type": "docs", "hidden": true},
    {"type": "style", "hidden": true},
    {"type": "perf", "hidden": true},
    {"type": "test", "hidden": true}
]

In this file, you enable the feat, fix, and change commit types. If you want to enable the other commit types, you can remove the hidden boolean and replace it with the section string and provide a title.

You can customize this file to use whatever types and section titles you like. For example, you could change the fix type to map to a “Bug fixes” section instead of “Fixed.”

Step 3 – Make some commits and open a pull request

In your repository, create a new branch and make a few commits. Be sure to prefix each commit with a commit type, like fix or change. Remember, if you don’t add a commit type to your commit message, it won’t be included in your repository.

After you finish your work, push your commits to your repository. Then open a merge request to merge in your changes into your main branch.

Step 4 – Generate your changelog

After you merge in your changes, return to your code editor to pull down the latest changes to your main branch. Then run the command npm run release.

You’ll see output like this in your terminal:

✔ bumping version in package.json from 1.0.8 to 1.0.9
✔ bumping version in package-lock.json from 1.0.8 to 1.0.9
✔ outputting changes to CHANGELOG.md
✔ committing package-lock.json and package.json and CHANGELOG.md
✔ tagging release v1.0.9
ℹ Run `git push --follow-tags origin main && npm publish` to publish

A few things to note here:

If you look at the changelog, you’d see all the commits made for version 1.0.9, sorted by commit type, and a link to the commit itself. End users can click on the link to the commit for more details.

Note: standard-version only bumped the PATCH version for this release because the release included bug fixes. If the release included a new feature, the MINOR version would’ve been bumped instead. See Semantic Versioning 2.0.0 for more details.

Step 5 – Push your changelog and tags

The last step is to push your newly created changelog and tags to your repository using the command git push --follow-tags origin [branch-name]. This command pushes any commits and tags to your repository.

One thing to note

This tutorial walks you through the basics of working with standard-version to automate versioning and changelog generation. If you do use standard-version for your open source project, your workflow will probably look different. For example, your team may choose to squash commits when merging in a MR. If that’s the case, you’ll want to make sure that your merge request title uses a commit type so it’s included in the changelog. Everyone has their own method.

Summary

standard-version is an excellent tool to help teams automate changelog generation and versioning. Going back to the example at the beginning of this tutorial, you could merge the 3.1.2-staging branch into your release branch and then run standard-version to generate your changelog, bump the version, and tag the release. Using automation tools like standard-version makes tracking changes to your project much easier!