fix(ci): packed consumer installs keep same-day dependency bumps on every Bun release (#6059)

* fix(ci): packed consumer installs keep same-day dependency bumps on every 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).

* fix(ci): keep the release-age parser's doc comment to one line
This commit is contained in:
Miguel Ángel
2026-10-22 11:28:16 +00:00
committed by GitHub
parent 8d6ceb7359
commit 2faf660ac1
3 changed files with 39 additions and 3 deletions
+3
View File
@@ -97,5 +97,8 @@
"@types/react-dom": "^19.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"engines": {
"bun": "1.4.4"
}
}
+11 -3
View File
@@ -479,7 +479,15 @@ function writeConsumerFixture(packDir, packedWorkspaces) {
export const CONSUMER_MIN_RELEASE_AGE_SECONDS = 24 * 60 * 60;
const BLOCKED_BY_AGE =
/No version matching "[^"]+" found for specifier "([^"]+)" \(blocked by minimum-release-age/g;
/No version matching "([^"]+)" found for specifier "([^"]+)" \(blocked by minimum-release-age/g;
/** Packages bun refused as too new, or null when its output does not pair a name with a range. */
export function ageBlockedPackages(stderr) {
const names = [...stderr.matchAll(BLOCKED_BY_AGE)].map(([, a, b]) =>
[a, b].find((name) => stderr.includes(`${name}@${name === a ? b : a} failed to resolve`)),
);
return names.length && names.every(Boolean) ? names : null;
}
export function installConsumer(dir, { args = [], env = process.env } = {}) {
const install = () =>
@@ -498,8 +506,8 @@ export function installConsumer(dir, { args = [], env = process.env } = {}) {
} catch (error) {
// A same-day dependency bump: every version its range allows is younger than the age, and the repo
// installed it already, so its tarball is served. Only those packages skip the age.
const blocked = [...`${error.stderr ?? ""}`.matchAll(BLOCKED_BY_AGE)].map((m) => m[1]);
if (!blocked.length) throw error;
const blocked = ageBlockedPackages(`${error.stderr ?? ""}`);
if (!blocked) throw error;
console.log(`Consumer install: newer than the release age, allowed: ${blocked.join(", ")}`);
writeFileSync(
join(dir, "bunfig.toml"),
+25
View File
@@ -7,6 +7,7 @@ import { dirname, join } from "node:path";
import { describe, it } from "node:test";
import { Worker } from "node:worker_threads";
import {
ageBlockedPackages,
CONSUMER_TSCONFIG,
countTypeErrorsByPackage,
installConsumer,
@@ -353,6 +354,30 @@ async function withRegistry(name, versions, run) {
}
}
describe("ageBlockedPackages", () => {
const blockedBy = (first, second, name, range) =>
`Resolving dependencies\nerror: No version matching "${first}" found for specifier "${second}" (blocked by minimum-release-age: 86400 seconds)\nerror: ${name}@${range} failed to resolve\n`;
it("names the package whichever order bun quotes it in", () => {
assert.deepEqual(ageBlockedPackages(blockedBy("fake-dep", "^1.1.0", "fake-dep", "^1.1.0")), [
"fake-dep",
]);
assert.deepEqual(ageBlockedPackages(blockedBy("^1.1.0", "fake-dep", "fake-dep", "^1.1.0")), [
"fake-dep",
]);
assert.deepEqual(
ageBlockedPackages(blockedBy("^2.0.1", "@scope/pkg", "@scope/pkg", "^2.0.1")),
["@scope/pkg"],
);
});
it("names none when bun's output does not say which token is the package", () => {
const unpaired = `error: No version matching "^1.1.0" found for specifier "fake-dep" (blocked by minimum-release-age: 86400 seconds)\n`;
assert.equal(ageBlockedPackages(unpaired), null);
assert.equal(ageBlockedPackages("error: fake-dep@^9.0.0 failed to resolve\n"), null);
});
});
describe("packed consumer install", () => {
/** Installs `deps` into a fresh consumer against the registry; returns the installed fake-dep version. */
function install(registry, dir, deps) {