Skip to content

Wait out registry propagation before deciding a version is unpublished - #116

Merged
ryanbliss merged 1 commit into
mainfrom
fix/release-tag-waits-for-registry
Sep 8, 2026
Merged

ryanbliss merged 1 commit into
mainfrom
fix/release-tag-waits-for-registry

Conversation

@ryanbliss

Copy link
Copy Markdown
Owner

Problem

The 0.11.1 Release run published all eight family packages successfully, then failed 4 seconds later in "Tag and create GitHub release (lockstep family)":

Error: create-github-release: @retreejs/create@0.11.1, @retreejs/babel-plugin-compiler@0.11.1 is not on npm, so v0.11.1 would point at an unpublished version. Fix: publish the missing package(s) (`npm run publish:packages` skips the ones already on npm), then rerun the Release workflow to create the release.
    at file:///home/runner/work/retree/retree/scripts/create-github-release.mjs:63:15

Both packages were published. From the run's attempt-1 log, the publish step reported + @retreejs/create@0.11.1 at 22:13:27 and + @retreejs/babel-plugin-compiler@0.11.1 at 22:13:33; the tag step read npm at 22:13:33-22:13:37. The six packages published 15-45s earlier were all visible; the two published in the last 10 seconds were not. npm accepts a publish before every read path serves it, so a single npm view right after publishing can miss the versions published last. Rerunning the job unchanged succeeded.

Solution

create-github-release.mjs now re-reads only the still-missing versions on a bounded backoff (2s, 4s, 8s, 16s, 30s — 60s total) before concluding a package is unpublished, logging each wait so the step is not silent. A genuinely unpublished package still fails the step, and the error now says how long it waited.

The polling lives in scripts/publish-package-selection.mjs as findUnpublishedVersions, next to the npmVersionState read it drives, with the registry read and the sleep injectable so it is unit-testable. The --dry-run preview passes no delays, so it still answers from the registry as it reads right now.

Alternatives considered

Have the publish step emit what it just published (step output or artifact) and tag from that. Rejected: it contradicts #110's "tag from registry state". The tag step deliberately runs when publishing failed, was skipped because everything was already on npm, or a missing package was published by hand — in all of those the run has no authoritative output to read, so the registry check would still be needed and the step output would only be extra machinery for the one case already covered.

Verification

  • npm run typecheck, npm run test (123 files, 1708 tests), npm run doctor, npm run lint:architecture all pass.
  • Three new cases in scripts/publish-package-selection.spec.mjs cover: no wait when everything is visible, waiting out a version that appears on a later read (and re-reading only the missing one), and reporting what is still missing plus the elapsed wait.
  • node scripts/create-github-release.mjs --dry-run on this branch still short-circuits on the existing v0.11.1 release.
  • No changeset: only scripts, workflow, and CONTRIBUTING change, none of which are published packages.

The release step reads npm right after the publish step, and npm serves a
publish it just accepted a few seconds later, so the last packages published
can still be missing. It now re-reads only the missing versions on a bounded
backoff (60s total) before failing, and says how long it waited.
@ryanbliss
ryanbliss merged commit af2adb0 into main Sep 8, 2026
3 checks passed
@ryanbliss
ryanbliss deleted the fix/release-tag-waits-for-registry branch September 8, 2026 22:34
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