Repository navigation
fix(ci): packed consumer installs keep same-day dependency bumps on every Bun release - #6059
Conversation
Edit accuracy: accurate 271 (base branch 271), smooth 155 of thoseThe gate passes. Quarantined, measured but not gated (0) Unstable (1)
|
vanceingalls
left a comment
There was a problem hiding this comment.
Reviewed at 063e74ed (two commits on f5873b80).
What holds
-
The parser fixes the real failure, not only the test fixture. I ran
bun install --minimum-release-age=86400against a local fake registry under the released Bun 1.4.4 and 1.4.3 binaries. Three shapes were tested:- a fresh package pulled in through an old registry package;
- two fresh packages (one scoped) pulled in through a
file:tarball, which is the real packed consumer's shape; - the same two as direct dependencies.
Both versions print the
<name>@<range> failed to resolveline in every shape, including transitive ones, and only the quoted pair is swapped.ageBlockedPackagesnamed exactly the blocked packages in all six runs, andinstallConsumerwent on to finish the install each time. -
It fails closed. If any match has no pairing line, it returns
nulland the original error is rethrown. A future format change can't turn into a wrong exclusion. -
The Bun pin takes effect. At the pinned commit,
oven-sh/setup-bun@0c5077e5falls back to$GITHUB_WORKSPACE/package.jsonwhen nobun-versionor file input is given (src/index.ts:27-29), readingpackageManagerbun@…first and thenengines.bun(src/utils.ts:124). Nosetup-bunstep in the repo sets a version exceptcanary-sunset.yml(latest, as the body says), and none of them runs before checkout. The root package isprivate, soenginesnever ships. -
Locally: under Bun 1.4.4, the
ageBlockedPackagesandpacked consumer installsuites pass 5/5.
Nit (non-blocking)
studio-drag-frames.ymlchecks out${{ inputs.ref || 'main' }}beforesetup-bun, so a bench run against a ref older than this PR reads that ref'spackage.jsonand gets the latest Bun. It's a manual bench and not a gate, so it's fine as is. Worth knowing if a bench result ever moves along with a Bun release.
CI: green at 063e74ed. All 8 required checks pass (Build, Typecheck, Test, Test: runtime contract, Tests on windows-latest, Render on windows-latest, Semantic PR title, regression). Test (support), which runs the same-day install test, is green on this head under the newly pinned Bun.
Verdict: APPROVE
Reasoning: The parser now pairs the name with the range from Bun's own output and fails closed on anything else. I checked that pairing against the real 1.4.3 and 1.4.4 binaries, including transitive and scoped packages. The engines.bun pin is what the pinned setup-bun reads.
— Via
…very Bun release Bun 1.4.4 swapped the quoted package and range in its minimum-release-age error, so the retry excluded the range instead of the package and the install failed again. The package is now the token that bun's "<name>@<range> failed to resolve" line pairs with the other one, and an unrecognised message fails visibly instead of excluding the wrong name. CI installs the newest Bun when nothing pins it, which let the 1.4.4 release turn every PR's support tests red mid-day. engines.bun in the root package.json pins it for every setup-bun step that does not set a version (packageManager would make corepack's pnpm refuse the repo).
063e74e to
a9ec524
Compare
vanceingalls
left a comment
There was a problem hiding this comment.
Re-reviewed at a9ec5247, which is the same two commits rebased onto 8d6ceb73. The push dropped my approval at 063e74ed (5613149370).
- The content hasn't changed.
scripts/verify-packed-manifests.mjs, its test andpackage.jsonhave the same blob ids ata9ec5247as at063e74ed(fc6ea3a0,06af0d7a,c332c9fc). - The rebase replaces #6058's flip. On main, #6058 (
3a0caeeb) flippedBLOCKED_BY_AGEto capture the second token, which reads 1.4.4's order only. This PR swaps that forageBlockedPackages, which pairs either order against the<name>@<range> failed to resolveline and fails closed. Everything I verified at063e74edstill applies: the real 1.4.3/1.4.4 binaries, transitive,file:, scoped and multi-package blocks, andsetup-bunreadingengines.bun.
CI: green at a9ec5247. All 8 required checks pass in the first CI run on this head (39768186756 and its siblings), with Test (support) green on the pinned Bun. A second pull_request run on the same head skipped its jobs after Detect changes.
Verdict: APPROVE
Reasoning: This is a clean rebase with byte-identical files. The only change is that it now supersedes the one-direction flip that landed on main.
— Via
What
Packed consumer installs keep same-day dependency bumps working on every Bun release, and CI stops picking up a new Bun mid-day.
Why
installConsumerretries an install that Bun refused under--minimum-release-age, excluding the refused packages. It read the package name as the first quoted token of Bun's error. Bun 1.4.4 (released 2026-10-22) swapped the two tokens:No version matching "fake-dep" found for specifier "^1.1.0" (blocked by minimum-release-age: 86400 seconds)No version matching "^1.1.0" found for specifier "fake-dep" (blocked by minimum-release-age: 86400 seconds)On 1.4.4 the retry excluded
^1.1.0, stayed blocked, and failed.verify-packed-manifests.test.mjs"installs a same-day dependency bump whose only matching version is an hour old" went red ("allowed: ^1.1.0"), so every PR'sTest (support)fails from the first run that downloaded 1.4.4. A release's packed consumer install of any same-day dependency bump would fail the same way.CI picked up 1.4.4 without a change in this repo because no
setup-bunstep pins a version, and with none given the action installs the latest release.Related work
Supersedes the one-line flip in #6058, which made the release-age regex capture the second quoted token. That fits Bun 1.4.4's message order only, breaks on the other order, and leaves Bun unpinned. This PR pairs the tokens structurally (
ageBlockedPackages), so either order works, and pins Bun withengines.bun. Rebased onto main with the conflict resolved in favour ofageBlockedPackages.How
scripts/verify-packed-manifests.mjs:ageBlockedPackages(stderr)reads both quoted tokens and takes as the package the one that Bun's<name>@<range> failed to resolveline pairs with the other. Both versions print that line (captured from 1.4.3 and 1.4.4 against the test's fake registry). If no such line pairs the tokens, it returnsnulland the original install error is rethrown, so an unknown future format fails visibly instead of excluding the wrong name.package.json:"engines": { "bun": "1.4.4" }. With nobun-versioninput,oven-sh/setup-bunat the pinned commit0c5077e5reads the rootpackage.json(src/index.ts:27-29,packageManagerbun@Xorengines.bun,src/utils.ts:124), so this one field pins Bun for everysetup-bunstep that does not set a version.packageManager: "bun@..."would do the same for setup-bun but makes Corepack's pnpm refuse the repo, and CI and publish runcorepack enable+pnpmfrom the root (ci.yml:325-326,publish.yml:119-120).canary-sunset.ymlstill asks forlatestexplicitly and is left as is.Test plan
ageBlockedPackageswith both Bun message orders and a scoped name, plus two messages that must name nothing.does not provide an export named 'ageBlockedPackages'); main's code under Bun 1.4.4 fails the same-day install test (allowed: ^1.1.0).node --test scripts/verify-packed-manifests.test.mjs22/22, 3 runs each under Bun 1.4.4 and 1.4.3.bun install --frozen-lockfilewith the newenginesfield;corepack pnpm@10.17.1 --versionfrom the repo root still runs;check:workspace-contracts,oxfmt --check,oxlintclean.Size
Under 100 lines on purpose: it unblocks
Test (support)on main for every open PR, so it ships alone rather than riding a larger change.