fix: unblock the release and make the registry publish retryable - #26
Merged
Merged
Conversation
The 0.10.1 release failed at the npm publish: E422 Unprocessable Entity - PUT https://registry.npmjs.org/@dxos%2fplugin-tictactoe Error verifying sigstore provenance bundle: Failed to validate repository information: package.json: "repository.url" is "", expected to match "https://github.com/dxos/plugins" from provenance Provenance is on, and npm validates the signed statement against the published `repository.url`, which the plugin never declared. The rejection lands after the signature has been written to the transparency log, so nothing warns first — the release is simply lost. `check-packages-published` now fails on a publishable plugin whose `repository.url` is absent or does not match `GITHUB_REPOSITORY`, alongside the existing never-published check, so the next plugin cannot repeat this. No changeset: 0.10.1 is bumped on `main` but was never published, so landing this lets the release retry and ship a correct 0.10.1. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SZ4ZdaPo9erkh5yF4eXh3Z
Contributor
🦋 No changeset foundThis PR changes plugin source but has no
|
The registry step was gated on `steps.changesets.outputs.published` and fed by `publishedPackages`, both of which exist only in the run that published to npm. npm is append-only, so after it accepts a version a re-run finds nothing to publish and skips the registry step entirely — the half that talks to two external services was the half with no way to retry, short of a version bump. Dispatching with `registry_only` now republishes the current versions to the registry and skips npm. Extracts the selection out of an inline `node -e` into `scripts/release-dirs.mjs` so both modes are testable: `ALL=true` takes every publishable plugin, otherwise `PUBLISHED` names the set. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SZ4ZdaPo9erkh5yF4eXh3Z
Both release scripts scanned `packages/*` and re-read each package.json to find the name and `private` flag — re-deriving what pnpm already knows from the workspace glob, and silently going wrong the day that glob changes. `pnpm list --recursive --depth=-1 --json` reports name, version, path and `private` directly, and drops the workspace root along with everything else not meant for npm. `repository` still comes from the manifest: pnpm does not report it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SZ4ZdaPo9erkh5yF4eXh3Z
`pnpm list --recursive --depth=-1 --json` already reports name, version, path and `private`, so the selection is a jq filter over it and does not need a script of its own. Drops release-dirs.mjs and the shared workspace helper; check-packages-published calls pnpm directly for the one field pnpm does not report, `repository`. Matches package names exactly. jq's `inside` compares strings by substring, so releasing a plugin whose name merely contains another's would have republished the other one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SZ4ZdaPo9erkh5yF4eXh3Z
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.
The 0.10.1 release failed at the npm publish (run 31265246246), and in diagnosing it a second problem surfaced: the registry half could not be retried at all.
1. The publish failure
release.ymlsetsNPM_CONFIG_PROVENANCE: 'true', so npm signs a statement naming the source repo and validates it against the published package'srepository.url.packages/tictactoe/package.jsonhas norepositoryfield, so the comparison is against"".Nothing warns first — npm signed and wrote the statement to the transparency log (
logIndex=2386003534) before the registry rejected the tarball.packages/tictactoe/package.json— addrepository(git+https://github.com/dxos/plugins.git,directory: packages/tictactoe).scripts/check-packages-published.mjs— fail a publishable plugin whoserepository.urlis missing or doesn't matchGITHUB_REPOSITORY, alongside the existing never-published check. Runs before the network calls, so it fails fast and works offline; locally it checks presence only.2. The registry publish could not be retried
The registry step was gated on
steps.changesets.outputs.published == 'true'and fed bypublishedPackages— both of which only exist in the run that published to npm. npm is append-only, so once a version is accepted,changeset publishskips it, reports nothing released, and the registry step never runs again. The half that talks to two external services (DXOS edge + the publisher's PDS) was the half with no retry path, short of burning a version.release.yml— aregistry_onlydispatch input republishes the current versions to the registry and skips npm.scripts/release-dirs.mjs— the selection moves out of an inlinenode -eblob into a script, so both modes are testable:ALL=truetakes every publishable plugin,PUBLISHEDnames the set otherwise.I left the channel order alone. Registry-first would also have avoided the trap, but a retry switch fixes it in both directions and costs less churn.
Verification
check-packages-published, both failure paths — a mismatch-only guard would have missed this bug, which was an absent field:release-dirs.mjs, every input shape the workflow can hand it:Workflow parsed and step conditions asserted:
changesetsgainsif: ${{ !inputs.registry_only }}, the registry stepif: ${{ inputs.registry_only || steps.changesets.outputs.published == 'true' }}. Onpushtheinputscontext is empty, so both evaluate as before.moon run :lintclean,pnpm formatapplied.Two things worth knowing
npm only holds a
0.0.0placeholder for@dxos/plugin-tictactoe—dist-tags.latestis0.0.0.check-packages-publishedpasses because it only asks whether the package exists, which is the right question for its purpose (trusted-publisher configuration), but no real version has ever shipped. 0.10.1 will be the first.No changeset, deliberately. 0.10.1 is bumped on
mainwith its changesets consumed but never published, so merging this leavesmainat 0.10.1 with nothing pending, andrelease.ymlgoes straight to the publish path and retries. A changeset would bump to 0.10.2 and strand 0.10.1.