Managing Releases with Changesets
Do you find managing releases of your Design System to be a pain? Are you tired of repeating yourself to write a changelog and release notes? Do you release too frequently, leading to upgrade fatigue for your consumers?
I've been using Changesets since 2022 and believe it's an excellent tool to help with all of the above questions. Let's dive in.
What is it?
"A tool to manage versioning and changelogs with a focus on multi-package repositories".
Changesets allows you to follow semantic versioning and puts you in control of when to cut a release. When you're ready, it'll publish your package(s), update a changelog file, and update the releases section in GitHub with this information.
It's very straight forward to use — simply run pnpm changeset
when your change is worth calling out for consumers of your package. Check in the markdown file it added, write some helpful information outlining the changes, and then put your pull request up for review like you would normally.
Let's quickly run through an example of a Changesets workflow. Say you're building a Design System that publishes to npm
.
- You put up a PR to add a new Alert component.
- You run
pnpm changeset
. - You select a
minor
version change, since we are adding new functionality. - You'll be prompted for a summary of the changes. We'll write something nice about our new Alert component, how to import it, when to use it, and lastly how to use it.
- It'll then ask you for confirmation of the changeset.
- A changeset is added to your changes as a markdown file.
- You commit this markdown file and push it to your branch. Let it merge in with your PR.
- Your PR merges, but it's not yet released to consumers. It's simply in
main
. - Changesets collects all open changes and creates a "Release Preview" PR (you can name this whatever you want).
- This PR keeps track of all changes that'll go out in the next release. It looks at the "largest change" to determine which versioning path it should take. So if you have 2
minor
updates and onepatch
, the next release will be aminor
update. If you have amajor
update and 500patch
changes, it'll bump it up to major. - Merging the "Release Preview" PR versions your package(s), creates a tag, and publishes to
npm
. Using the changeset markdown files you created earlier, the changelog file is automatically updated with this information. If you're on GitHub, it creates a nice release log for you too using the same changeset files.
After this process, consumers can use your changes and have all of the information they may need about the release. Since you follow semantic versioning, their expectations are properly set with each version update.
If all above makes sense, you can probably stop here and go give it a try — otherwise, I'll ramble a bit longer about some of my favorite things with Changesets.
Respect Semantic Versioning
Semantic versioning is a key piece of building and maintaining a JavaScript package. It communicates to your consumer what happened in the release, whether it's a breaking change that may require some of their time to upgrade, a minor version update with new features they can leverage, or a patch change to fix some bugs.
Unfortunately, semantic versioning isn't always respected by library authors. This is frustrating. But for packages you own, you can ensure this is followed quite easily — especially when using Changesets. With each pnpm changeset
command you run, Changesets explicitly asks you what type of change (major, minor, or patch) is in your pull request.
Follow semantic versioning. Your users will appreciate it! No one wants to be surprised with a breaking change in a minor or patch release.
Control When to Release
Being able to decide when to release is huge. Sometimes you want to batch a bunch of changes together. Maybe you're drastically changing all of your design tokens. Or maybe you're going through a really large refactor that'll enable future features. Maybe you are rewriting a large component and you want to break the changes into separate PRs to make it easier to review, but you don't want to cut a release until you're completed. Rather than having to do feature branches, you can let everything merge into main
without any worry of it being released to consumers too early.
Compare this to the semantic-release approach where it'll cut a release with every PR merge by default based on the commit message. Overall, I think Changesets is a bit simpler by collecting markdown files and tracking along with a Release Preview PR. Simply merge that PR when you're ready to release and be on your way.
Don't worry about when to merge. Instead always be shippin' / mergin'!
Automated Changelogs and Release Notes
I really like the automated changelogs and release notes. As mentioned above, Changesets allow you to write descriptions of each change in markdown. I typically add code examples in my release notes, as it makes it easier for folks to "see" the changes.
Part of my job is to work with teams and communicate changes that go into our Design System. Putting detailed information in a changeset makes my life a bit easier, even when your documentation is really great. Now it's in the changelog, the release note, and the docs.
Want an example? Here you go - check this out.
Releases link directly to the pull request and commit(s) for each change as well. This makes it helpful for consumers to get more information and context. I dig it.
Other Niceties
When you're in a monorepo setting, if a few of your packages are interdependent, it'll orchestrate the releases properly between all of them. This has been really nice. No more worrying about having to manually bump versions or ensure changes are in lock step with one another.
My favorite thing is that they aren't clever with how they work — there aren't any surprises if you modify their generated changeset markdown files. Things flat out work really well and it's pretty difficult to find yourself in a weird state. Accidently set something as a patch
, but it should be a major
? Go in and edit the markdown file and that's it. Once your changes are in main
, it'll update your Release Preview. I really appreciate the simplicity with Changesets.
Using GitLab and private registries? Check out this step-by-step guide from Haley Ward.
That's All I've Got
Anyway, that's all I got! Big fan of Changesets. There are some other tools like release-plan that look really promising. I'll report back as I play with it. Thanks and see ya next time!
👋