fix(ci): one package manager, one lockfile — publish uses pnpm#12
Merged
Conversation
package.json declares packageManager: pnpm@9.15.4 and ci.yml runs
pnpm install --frozen-lockfile, but publish.yml ran npm ci against a second
lockfile nothing else read. So a package.json change could pass CI and still
kill the publish — which is exactly how v3.6.0 died:
npm error Invalid: lock file's @blockrun/clawrouter@0.12.220
does not satisfy @blockrun/clawrouter@0.12.223
CI was green (pnpm-lock.yaml synced) while npm's lockfile still pinned 0.12.220 —
the very bundle that broke every consumer. The release published nothing and,
since the trigger is release:published with no workflow_dispatch, a re-run just
re-checked-out the same bad tag; 3.6.1 had to be cut instead.
publish.yml now installs with pnpm (matching ci.yml); pack/publish stay on npm
since they read package.json, not a lockfile, and npm publish --provenance is
what wires the OIDC attestation. package-lock.json deleted and gitignored so the
second source of truth cannot come back.
Verified the publish job's exact sequence with only pnpm-lock.yaml present:
pnpm install --frozen-lockfile, pnpm run build, npm pack --dry-run all pass;
tarball is @blockrun/llm@3.6.1, 7 files, peerDependenciesMeta.optional intact.
197 tests, typecheck green.
VickyXAI
pushed a commit
that referenced
this pull request
Jul 15, 2026
…lish #9: BlockRun's ERC-8021 service code s:["blockrun"] is now attached to every payment this SDK signs (EVM + Solana). The signed authorization is byte-identical — extensions sits on the outer envelope, not in the EIP-712 message/types/domain. Verified with a real settle on Base rather than unit tests alone: built the branch into @blockrun/mcp and drove one live x402 call (64.902027 -> 64.899027); CDP accepted the unregistered service code. #12: publish.yml now installs with pnpm, matching ci.yml and packageManager. package-lock.json is gone. This release is the first through that path — the old npm ci step would fail outright now, which is the point: one lockfile, one truth.
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 trap
package.jsondeclares"packageManager": "pnpm@9.15.4"andci.ymlrunspnpm install --frozen-lockfile— butpublish.ymlrannpm ciagainst a second lockfile nothing else read.So a
package.jsonchange could pass CI and still kill the publish. That is exactly how v3.6.0 died:CI was green (
pnpm-lock.yamlsynced) while npm's lockfile still pinned 0.12.220 — the very bundle that broke every consumer for four days. The release published nothing, and since the trigger isrelease: publishedwith noworkflow_dispatch, a re-run just re-checked-out the same bad tag. 3.6.1 had to be cut instead.Two lockfiles means two sources of truth and one of them is only exercised at release time — the worst possible moment to discover it drifted.
The fix
publish.ymlinstalls with pnpm, matchingci.ymland the declaredpackageManagerpack/publishstay on npm — they readpackage.json, not a lockfile, andnpm publish --provenanceis what wires the OIDC attestationpackage-lock.jsondeleted and gitignored, so the second source of truth cannot come backVerified
Ran the publish job's exact sequence with only
pnpm-lock.yamlpresent:197 tests, typecheck green.