Skip to content

Gate each publish on its own registry, not a parsed stdout flag - #14

Merged
brentrager merged 2 commits into
mainfrom
fix/per-registry-publish-gate
Aug 20, 2026
Merged

brentrager merged 2 commits into
mainfrom
fix/per-registry-publish-gate

Conversation

@brentrager

Copy link
Copy Markdown
Contributor

The problem

Every non-npm publish step was gated on steps.changesets.outputs.published. changesets/action derives that flag by parsing publish stdout, which fails open two ways — and both happened for real today, in sibling repos:

  1. npm published in an earlier run. The retry finds nothing new to publish, so the flag is false, so PyPI, crates.io, the Go tag and NuGet all skip — a green run that ships nothing. This is exactly how smooai-logger 4.5.2 reached npm and PyPI and no other registry.
  2. @changesets/cli 3.x renamed the line the action parses (🦋 New tag: → ◇ Successfully published:). A dependency bump silently switched every non-npm publish off in smooai-config, stranding four registries at 6.11.5 while 6.11.6/6.11.7/6.12.0 went to npm alone — with every release reporting success.

A release gate keyed on another tool's stdout is a guard that inverts on that tool's cosmetic change.

The fix

scripts/check-registries.mjs reports which registries already carry package.json's version. Each publish step now gates on its own registry, so a retry ships exactly what is missing, and a final step fails the run if npm shipped a version the others didn't.

NuGet is reported but not asserted. Its index lags an accepted push by minutes to tens of minutes (measured at 14+ today), so holding it strictly would redden successful releases — and a guard that cries wolf gets deleted. It keeps its own protection: dotnet nuget push exits non-zero on a real failure, and the per-registry gate skips it only when the version is genuinely there.

Verified by making it fail first

$ node scripts/check-registries.mjs            # real state
  ✓ npm  ✓ pypi  ✓ crates  ✓ nuget  ✓ go       exit 0

$ # PyPI probe pointed at a nonexistent package, npm left real:
  ✓ npm  · pypi  ✓ crates  ✓ nuget  ✓ go
  ✗ npm published 0.4.0 but pypi did not.      exit 1

Ported from the working model in SmooAI/file#82. Pearl th-a40d35.

🤖 Generated with Claude Code

https://claude.ai/code/session_0152bbE1veqfG1SVJdyLCBxC

steps.changesets.outputs.published is derived by parsing publish stdout, so
it fails open two ways — both observed for real today. If npm published in
an earlier run, a retry finds nothing new, the flag is false, and all four
remaining registries skip: a green run that ships nothing (this is how
smooai-logger 4.5.2 reached npm and PyPI and nowhere else). And
@changesets/cli 3.x renamed the line the action parses, which silently
switched every non-npm publish off in smooai-config while releases stayed
green.

Each publish now gates on whether its own registry has package.json's
version, so a retry ships exactly what is missing, plus a final assert that
fails when npm published a version the others did not. NuGet is reported but
not asserted: its index lags an accepted push by 14+ minutes, and a guard
that reddens successful releases gets deleted.

Verified by making it fail first: pointing the PyPI probe at a nonexistent
package while npm stayed real exits 1 and names pypi.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0152bbE1veqfG1SVJdyLCBxC
@changeset-bot

changeset-bot Bot commented Aug 20, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a277064

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

This PR includes changesets to release 1 package
Name Type
@smooai/audit Patch

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

Re-verified after formatting: the report is unchanged and the positive
control still exits 1 (PyPI probe pointed at a nonexistent package while
npm stays real).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0152bbE1veqfG1SVJdyLCBxC
@brentrager
brentrager merged commit 4e17d0e into main Aug 20, 2026
1 check passed
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.

1 participant