fix(release): npm needs an explicit dist-tag for a prerelease, chosen from what the registry holds - #93
Merged
krzysztof-smartdataengines merged 1 commit intoSep 27, 2026
Conversation
…t the registry holds Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
krzysztof-smartdataengines
deleted the
fix/npm-dist-tag-for-prereleases
branch
September 27, 2026 08:39
This was referenced Sep 27, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The release workflow could not have published a release candidate to npm. npm 11, which the
publishing job installs (
npm@11.15.0), refuses a prerelease without an explicit tag:The job ran
npm publish "$tarball" --access public, so the planned first run,0.1.0-rc.1, wouldhave failed at the publish step, after the gate and the reviewer had both said yes. The runbook's
hand-made first publish (
0.1.0-dev.0) would have failed the same way. Found by reading the CLI'ssource before the first release, because the publishing half of this workflow cannot be rehearsed.
A fixed tag is wrong one way or the other:
latestfor every publish would put each candidate over the last final;nextfor every prerelease would leave an unpinned install on the version published by handuntil the first final.
What changed
tools/npm_dist_tag.pychooses the tag from the versions the registry already holds, bySemantic Versioning precedence:
latest;latestwhile no final exists, because an unpinnedpip installgets the newestprerelease on PyPI too;
nextonce a final exists.It refuses, for a person to decide:
It reads
npm view ... versions --jsonas npm prints it: a list, or a string when there is oneversion.
release.yml:the publishing job, which must not check out the repository, receives the tag as an output;
--tagexplicitly;docs/publishing.md: the hand-made first publish isnpm publish --access public --tag latest, with the reason and the npm source quoted, and §5.2states the rule.
Tests
test_release.py:rc.10afterrc.9;npm publishin the workflow or the runbook without--tag;On
mainthe two workflow tests fail for the stated reason: the publish line has no--tag, andthe build job has no
dist_tagoutput.check_contexts.pystill passes. The publishing job holdsid-token: writebehind itsenvironment and checks nothing out, and every action is pinned to a SHA.
Mutations on the committed branch: 10 killed and a control survived. The killed mutations are:
latest, or alwaysnext;make checkon the head313b972, rebased on feat: Python 3.14 and Node 24 and 26, tested and claimed #92, with both live engines:frozen-verification.live.test.ts, exceeded vitest'sdefault 5 s timeout. Nothing here touches TypeScript. The test ran while this machine was
shared with another session's integration battery (load average about 4.6 on four threads).
Eleven isolated reruns of that file followed. Ten passed; one failed another of its tests, and
that output was not kept. The TypeScript half of
make checkrun again on the same head passed999 of 999, at a load average of 5.5. CI runs on unshared runners.
The mutation run was repeated on the rebased head, with the same result.
🤖 Generated with Claude Code