Skip to content

chore: upgrade Changesets to v3 - #478

Merged
dferber90 merged 1 commit into
mainfrom
upgrade-changesets-v3
Aug 17, 2026
Merged

chore: upgrade Changesets to v3#478
dferber90 merged 1 commit into
mainfrom
upgrade-changesets-v3

Conversation

@dferber90

Copy link
Copy Markdown
Collaborator

Purpose

This pull request changes Changesets from v2 to v3. Changesets v3 is the first major release after v2. All the Changesets packages are now ES modules, and the dependency tree is much smaller.

Dependency changes

ItemBeforeAfter
@changesets/cli2.31.03.0.0
@changesets/changelog-github^0.7.0^1.0.0
changesets/actionv1.7.0v2.1.0
engines.node (root)^20.19.0 || >=22.12.0^22.11 || ^24 || >=26

Notes about these changes:

  • The v1 action supports only Changesets v2. The v2 action shows an error if the project has Changesets v2.
  • Changesets v3 needs Node.js ^22.11 || ^24 || >=26. The new value of the root engines.node field shows this requirement. The 15 released packages in packages/* keep their own engines values. This change does not affect the users of the Flags SDK.
  • The CI jobs use .node-version (22.x) or Node.js 24. Both values agree with the new requirement.
  • The lockfile is 218 lines smaller. The Changesets tree now has 39 dependencies, and not 95.

Peer dependency version increases

The blog post gives the name "Less aggressive peer dependency bumping" to this change:

  • Changesets v2 gives a major increase to a peer dependent when the dependency gets a minor or a major increase.
  • Changesets v3 gives a patch increase, and only when the new version leaves the declared range. The author can add an explicit major changeset for the dependent if the new version breaks it.

This repository had an experimental option for the same purpose:

"___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
"onlyUpdatePeerDependentsWhenOutOfRange": true
}

This pull request removes the option, because Changesets v3 makes it redundant. The assemble-release-plan package in v3 does not read the option. The option name warns that it can change in a patch release. Therefore it is better to not use it.

@flags-sdk/vercel is the only package that has an internal peer dependency. It declares "flags": "*". This range accepts all versions, so a release of flags never gives @flags-sdk/vercel a version increase. This is true before and after the change.

Test results

A small test workspace shows the behavior. The lib package gets a minor increase from 4.3.0 to 4.4.0. Two packages have lib as a peer dependency.

CLIOptionstar-dep (peer *)caret-dep (peer ^4.3.0)
2.31.0trueno increaseno increase
2.31.0removed1.4.62.0.0 (major)2.0.03.0.0 (major)
3.0.0trueno increaseno increase
3.0.0removedno increaseno increase

The next table shows a major increase of lib from 4.3.0 to 5.0.0. The new version leaves the ^4.3.0 range of caret-dep.

CLIOptioncaret-dep (peer ^4.3.0)
2.31.0true or removed2.0.03.0.0 (major)
3.0.0true or removed2.0.02.0.1 (patch)

The two tables show two results:

  1. Changesets v3 gives a patch increase in place of a major increase, and it still reacts when the new version leaves the range.
  2. The option has no effect in v3.

Other configuration changes

ignore is now empty

Changesets v2 versions private packages by default. Changesets v3 does not. All 8 packages in the ignore list are private, so the list is no longer necessary. The migration guide recommends this change.

The privatePackages.version option stays at the default value false. A test run of changeset version with a minor changeset for flags changed only packages/flags. It did not change the 9 private packages that depend on flags.

format is now false

Changesets v2 includes a copy of Prettier and formats the new changelog text with it. Changesets v3 removes this copy and looks for a formatter in the project.

This repository uses Biome. Changesets removes Biome from the list for auto-detection, and the repository has no Prettier, Oxfmt, Deno, or dprint configuration. Auto-detection therefore finds no formatter. The explicit value false makes this result clear and stable, because auto-detection also looks in the parent directories of the checkout.

The output text does not change. Change this value to auto if you add a supported formatter later.

$schema points to @changesets/config@4

Changesets v3 uses @changesets/config v4.

Release workflow changes

The v2 action renames its inputs. The action shows an error if it finds an old name. This pull request makes these changes in .github/workflows/release.yml:

  • publishpublish-script
  • versionversion-script
  • The action removes the commitMode input. The GitHub API is now the default method to push the release commit and the tags, so the workflow does not need a value. The comment at the top of the file explains this. Set push-with-git-cli: true to use the Git CLI again.
  • The workflow no longer sets the GITHUB_TOKEN environment variable for the action step. The v2 action gives this variable to the version script and to the publish script. It takes the value from the github-token input, and this input defaults to the token of the workflow. @changesets/changelog-github therefore still gets a token. The v2 action also fails if a GITHUB_TOKEN environment variable and the github-token input have different values.

The snapshot job keeps its GITHUB_TOKEN environment variable, because it calls the CLI directly.

A new comment in the snapshot job explains one more change: changeset version now exits with code 1 if it finds no unreleased changesets. A snapshot needs a minimum of one changeset, so this exit code correctly stops the job. The log shows the message No unreleased changesets found.

The release job does not have this risk. The action calls the version script only when the repository has changesets.

Items with no effect on this repository

  • The tag command has the new name git-tag. This repository does not use the command. The old name still works as an alias.
  • The --sinceMaster flag is no longer available. This repository does not use the flag.
  • useCalculatedVersionForSnapshots has the new name snapshot.useCalculatedVersion. This repository already uses the new name.
  • access: "private" is no longer valid. This repository uses "public".
  • main is the new default value of baseBranch. The explicit value stays in the file, because it does no harm.
  • Changesets v3 ignores publishConfig.registry when it looks for unpublished packages. No package in this repository sets this field.
  • The repository is not in prerelease mode, so the new .changeset/pre/ directory is not relevant now.
  • changeset publish --no-git-tag --tag snapshot and changeset version --snapshot <name> keep the same behavior.

Verification

  • pnpm install --frozen-lockfile completes with no error.
  • pnpm changeset --version prints 3.0.0.
  • pnpm changeset status completes with no error.
  • pnpm changeset version with a test changeset for flags gives a correct changelog entry. It changes only packages/flags. This test changeset is not part of the commit.
  • pnpm exec biome check finds no problem in the changed files.
  • node scripts/validate-packages.mjs reports All packages valid.

This pull request changes only the development dependencies and the release configuration. No released package changes, so it needs no changeset.

🤖 Generated with Claude Code

Changesets v3 is the first major release since v2. All packages are now ES
modules, and the dependency tree is smaller.
- @changesets/cli 2.31.0 -> 3.0.0
- @changesets/changelog-github ^0.7.0 -> ^1.0.0
- changesets/action v1.7.0 -> v2.1.0 (v1 supports only Changesets v2)
- root engines.node -> ^22.11 || ^24 || >=26, the requirement of the new CLI
Remove the onlyUpdatePeerDependentsWhenOutOfRange experimental option.
Changesets v3 gives a peer dependent a patch increase, and only when the new
version leaves the declared range. This makes the option redundant for the
release plan.
Empty the ignore list. Changesets v3 does not version private packages by
default, and every ignored package is private.
Set format to false. Changesets v3 no longer bundles Prettier, and it excludes
Biome from formatter auto-detection.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Dominik Ferber <1765075+dferber90@users.noreply.github.com>
@vercel

vercelBot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
flags-playgroundReadyReadyPreviewAug 17, 2026 8:00am
flags-sdk-devReadyReadyPreviewAug 17, 2026 8:00am
shirt-shopReadyReadyPreviewAug 17, 2026 8:00am
shirt-shop-apiReadyReadyPreviewAug 17, 2026 8:00am

@socket-security

Copy link
Copy Markdown

@dferber90
dferber90 merged commit 5838f58 into mainAug 17, 2026
22 checks passed
@dferber90
dferber90 deleted the upgrade-changesets-v3 branch August 17, 2026 11:06
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@dferber90@AndyBitz