Skip to content

Changesets

Rishhi Balakrishnan edited this page Dec 1, 2023 · 14 revisions

Changesets

Last updated June 7 2023

We use a modified version of the changesets workflow to track changes that we want to communicate to customers or partners.

A changeset is a separate concept from either a changelog or release notes, but they are related. The changeset carries with it two key bits of information:

  • the packages affected by the change
  • a Markdown-formatted description of the change

Storing this information directly in git metadata such as commits is problematic because once written, git metadata cannot be changed without disrupting other contributors. This means that when we do a release and generate the changelogs, any tweaks we want to make must be made and stored elsewhere. Changesets allow us to review and fix change announcements just like code. Changesets are stored on the file system in a .changeset folder in the root of the release group (or package, for independent packages).

A changeset is a Markdown file with YAML front matter. The contents of the Markdown is the change summary which will be written to the changelog and the YAML front matter describes what packages have changed and what semver bump types they should be (for the FluidFramework repo the bump types are determined by the target branch).

---
"@myproject/cli": minor
"@myproject/core": minor
---

Change all the things

This is useful because it breaks change tracking into two steps:

  1. Adding a changeset - can be done in a PR, by a contributor, while the change is fresh in their mind.
  2. Releasing/versioning - combines all changesets and writes changelogs, which can then be reviewed in aggregate.

Note: The default changesets workflow and tools, which we are using, include the "bump type" (major | minor | patch) for each package in the changeset. Within the FluidFramework repo, the bump type is determined by the branch the change is merged to.

Terminology

Package – A self-contained tarball of code and metadata that is published to an npm feed. The smallest component of a release. Also called a library.

Release group – A collection of packages that we version and release together.

Release – A version of a package or release group that has been published to public npm. Importantly, our releases can contain multiple packages in the case of release groups.

Changelog – A file that is typically included in a package that lists the changes per version of the package. Typically called CHANGELOG.md. Sometimes this is just a list of commits, but it’s more useful when organized around things customers care about: new features, major improvements, breaking changes, etc. Example changelog: https://github.com/microsoft/FluidFramework/blob/main/packages/runtime/container-runtime/CHANGELOG.md

Release notes – A curated collection of all the changes in a particular release, including new features, breaking changes, and deprecations. Because we release multiple packages (dozens at a time in the case of client), we can’t expect people to read the individual changes in each package. Release notes are critical because they aggregate the changes across packages into a readable, useful format. Example release notes: https://github.com/microsoft/FluidFramework/releases/tag/client_v2.0.0-internal.3.0.0

Changesets and CI

Changesets are not fully automated yet. For now, PRs that need changesets are manually identified and labeled with the changeset-required label. If the PR is labeled changeset-required (only added manually at this point), then it will be checked for a changeset. If one is missing, then a comment will be added to the PR saying that a changeset is needed, including a link to this documentation.

A note about tools

We intentionally use as little custom tooling as possible in our implementation of changesets. We are re-using some of the changesets CLI and the schema they defined, even though it does not match our needs fully. This is an intentional choice motivated by two things: (1) developing and maintaining custom tooling is costly and (2) our needs remain quite dynamic, and it is foolish to believe we know enough about our needs to invest heavily in custom tools and "get it right." Rather, we are using the tools as they are so that we can more quickly learn.

You should not read this, though, as a reason to not complain about friction with the tools! We need to know what works and what doesn't so we can make better decisions about what customizations we should invest in. So please share your feedback about those rough edges with us!

Adding a changeset to a PR

Note: the following only applies to the client and server release groups. For independent packages or other release groups, contact @tylerbutler.

You can add a changeset to your PRs manually or by using the pnpm flub changeset add command.

Adding a changeset using pnpm flub changeset add --releaseGroup <releaseGroup>

To add a changeset, run pnpm flub changeset add --releaseGroup <releaseGroup> from the root of the release group. You will be prompted to select the affected packages. By default the CLI will show what packages have changed relative to main to make it easier to select affected packages, but you can compare with any branch by passing the --branch <BRANCH> flag (e.g. --branch next. The output is completely editable after the CLI is used so don't worry about "getting it right." You can always fix it up!

Manually adding a changeset

To manually add a changeset, add a randomly named markdown file to the .changeset folder in the root of the release group. Make sure to include the metadata about what packages are affected!

Adding an empty changeset

You can add an empty changeset using the command pnpm flub changeset add --empty. Remember to add details about the change, including the metadata about what packages are affected!

How do I know what packages to include in the changeset?

Each package in the changeset will have a changelog entry with the contents of the changeset. In other words, if you list a package in a changeset, you're saying that the contents of the changeset are relevant to that package. You do not need to include every package that was changed in a given PR. For example, if you deprecate a class in packageA and replace the use of the deprecated class in packageB, then packageB probably shouldn't be included in the changeset, while packageA should be.

Which PRs require changesets?

Any change that should be communicated to customers or partners should have a changeset. Stated differently, changes without a changeset are "invisible" to customers; changesets are how we track what needs to be communicated with partners and customers. We are discussing how to automate flagging some PRs, but for now it's manual.

Every upgrade of a server or common package in the client release group should have a changeset to ensure clarity about upgrades and prevent unexpected issues. Each changeset should detail any new functionalities, describe bugs fixed in the upgrade, and identify any potential breaking changes. It should also include a link to the release notes or changelog of the upgraded package for easy reference. For example, a changeset should exist when we do major updates to server or common packages.

Do I need to add a changeset with the change, or can I add it later?

You should add a changeset with every change that should be communicated, even if it is empty. The contents of the changeset can be updated at any time before release, but adding the changeset with the relevant change makes it easier to link commits to changelog entries. The presence of the changeset signals "This change contains something that should be communicated to customers. I may not know exactly what should be written yet, but I know it needs to be communicated." You can always add an empty changeset if you really don't know what to communicate to customers yet.

When will we release a version using the changesets?

We are aiming for the 2.0.0-internal.5.0.0 major release.

More questions?

Our changesets FAQ may answer them. If not, contact @tylerbutler.

Clone this wiki locally