Skip to content

fix(version): exit with code 1 when no unreleased changesets found - #1860

Merged
Andarist merged 5 commits into
changesets:nextfrom
mixelburg:fix/version-no-changesets-exit-code
May 4, 2026
Merged

Andarist merged 5 commits into
changesets:nextfrom
mixelburg:fix/version-no-changesets-exit-code

Conversation

@mixelburg

Copy link
Copy Markdown
Contributor

Summary

Closes #1815

changeset version currently exits with code 0 when no unreleased changesets are found, even though it has done nothing. This makes CI pipelines unable to detect the no-op case, which can lead to subtle bugs — for example when using --snapshot mode:

# No changesets exist
$ npx changeset version --snapshot canary
🦋  warn No unreleased changesets found, exiting.
$ echo $?
0
# ⚠️ Publish still runs! Packages get published with wrong version tags
$ npm publish --tag canary

Changes

  • packages/cli/src/commands/version/index.ts: Replace return with throw new ExitError(1) when no unreleased changesets are found
  • packages/cli/src/commands/version/version.test.ts: Update the no-changesets test to assert that an ExitError is thrown with code 1
  • .changeset/fix-version-no-changesets-exit-code.md: Changeset describing the patch

Migration

CI pipelines that currently call changeset version and ignore the exit code will need to handle the new exit code 1. A typical pattern would be:

changeset version --snapshot canary || exit 0  # ignore if no changesets
# or
if changeset version --snapshot canary; then
  npm publish --tag canary
fi

Previously, 'changeset version' would warn about no changesets and
then exit successfully (code 0), making it difficult to detect in CI
pipelines when the version step was a no-op.

This was especially problematic when using '--snapshot' mode: if
there were no changesets, the subsequent publish step would still run
and could publish packages with incorrect version tags.

Throwing ExitError(1) instead of silently returning ensures that CI
pipelines can detect and handle the no-changesets case.

Fixes changesets#1815
@changeset-bot

changeset-bot Bot commented Feb 28, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 21e5fe2

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@changesets/cli Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@codecov

codecov Bot commented Feb 28, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.85%. Comparing base (a0b5326) to head (21e5fe2).
⚠️ Report is 1 commits behind head on next.

Additional details and impacted files
@@           Coverage Diff           @@
##             next    #1860   +/-   ##
=======================================
  Coverage   81.85%   81.85%           
=======================================
  Files          54       54           
  Lines        2441     2441           
  Branches      715      716    +1     
=======================================
  Hits         1998     1998           
  Misses        401      401           
  Partials       42       42           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Andarist
Andarist requested a review from bluwy February 28, 2026 23:18
@Andarist

Andarist commented Mar 2, 2026

Copy link
Copy Markdown
Member

This is a breaking change. I'm a little bit on the fence right now and I'd prefer not introduce those in a minor release.

@bluwy

bluwy commented May 4, 2026

Copy link
Copy Markdown
Member

Should we move this to the next branch? I think this is an ok change.

Comment thread .changeset/fix-version-no-changesets-exit-code.md Outdated
@Andarist
Andarist changed the base branch from main to next May 4, 2026 09:20
Comment thread .changeset/fix-version-no-changesets-exit-code.md Outdated
@Andarist
Andarist merged commit 92b1c1b into changesets:next May 4, 2026
7 checks passed
@github-actions github-actions Bot mentioned this pull request May 4, 2026
ByronDWall pushed a commit to commercetools/nimbus that referenced this pull request Sep 23, 2026
…1995)

* ci(release): upgrade changesets/action to v2 for @changesets/cli v3

@changesets/cli v3 no longer prints the "New tag: <pkg>@<version>" lines that
changesets/action v1.9.0 scraped to learn which packages were published. The
action therefore saw zero published packages: it pushed no git tags, created no
GitHub releases, and set published=false -- while npm publishing itself
succeeded. 3.6.0 reached npm with no GitHub release history because of this,
and the publish step still reported success.

Two v3 breaking changes combined to produce the failed run:

- Published-package detection moved from stdout parsing to a shared output file
  named by CHANGESETS_OUTPUT (changesets/action#678). Action v1 has no such
  support and reported published=false, which skipped tagging and releases and
  also un-gated the canary step below.
- `changeset version` now exits 1 when there are no unreleased changesets
  (changesets/changesets#1860); v2 exited 0 silently. That turned the
  un-gated canary step into a hard job failure.

Upstream treats these as a matched pair and action v2 validates it, refusing
CLI v2 (changesets/action#699). There is no equivalent check in v1 for CLI v3,
which is why the mismatch degraded silently instead of failing fast.

Changes:

- changesets/action v1.9.0 -> v2.1.2, using v2's renamed kebab-case inputs and
  passing the app token through the `github-token` input, which is now required
  for custom tokens. `commitMode: github-api` is dropped because v2 uses the
  GitHub API by default.
- Guard both canary steps on the presence of changeset files, so an emptied
  .changeset/ is a clean skip rather than exit 1.
- Add a step asserting that the version present on npm has a matching git tag,
  so a silent tagging failure fails the job instead of reporting success.
- Remove scripts/print_release_version.sh and its step. Its output was read
  nowhere in the workflow, its exit code was swallowed by the surrounding
  command substitution, and it ran `changeset version` followed by
  `git reset --hard` inside the release job.

Co-Authored-By: Claude Opus 5 <[email protected]>

* ci(release): trim the comments added with the changesets v2 upgrade

The explanatory blocks restated the commit message and PR description, which
git blame already reaches, and ran six to eight lines in a file whose idiom is
one- to three-line constraint notes. Keep only what is not visible in the code
and would be re-broken if removed: that the action and CLI majors move
together, that the tag check is deliberately independent of the action's own
report, and why the canary steps test for changeset files before versioning.

Co-Authored-By: Claude Opus 5 <[email protected]>

---------

Co-authored-by: Claude Opus 5 <[email protected]>
Sign up for free to 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.

changeset version should return a non-zero error code if there are no changesets

4 participants