Skip to content

Commit 1a7616f

Browse files
fix(release): the ubuntu smoke never hard-fails a mismatched-platform tarball, and two stale test citations
MEASURED on the real p9a/platform CI run: npm treats every explicitly-named install argument as REQUIRED regardless of the wrapper's own optionalDependencies, so a mismatched-platform tarball (darwin-arm64 on an ubuntu runner) refused the WHOLE offline install with EBADPLATFORM -- not just its own package. smoke-installed.ts now excludes a bin-only package from the npm install command line when its os/cpu does not match the current host, answering its check as a SKIP without ever installing or spawning it. Also: the platform tarball ships no bin/ entry at all on a host that never built the binary (an empty directory is never packed), so the pack test's bin/-presence assertion is now host-gated; and two WS-13 citations in packages/conformance still quoted release-pack.test.ts's/build-packages.test.ts's pre-rename test titles.
1 parent 8eea600 commit 1a7616f

4 files changed

Lines changed: 97 additions & 13 deletions

File tree

packages/conformance/src/conformance.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -958,12 +958,12 @@ const PHASE_7A_ROWS: ConformanceRow[] = [
958958
bullet: "the publish pipeline packs, scans the TARBALL's contents, and imports every publishable package's every declared exports subpath from a real installed tarball",
959959
status: "new",
960960
citations: [
961-
{ file: `${SCRIPTS}/release-pack.test.ts`, testName: "the publishable set is exactly R-7-1's five packages -- excludes the private runtime and the unpublished (R-7-2) platform package" },
961+
{ file: `${SCRIPTS}/release-pack.test.ts`, testName: "the publishable set is exactly R-7-1's five JS packages PLUS the darwin-arm64 platform package (P9a-3) -- excludes only the private runtime" },
962962
{ file: `${SCRIPTS}/release-pack.test.ts`, testName: "catches all seven categories in one pass over one fixture" },
963963
{ file: `${SCRIPTS}/release-pack.test.ts`, testName: "P7a fix wave (item 9): NO tarball ships a test file -- verified via `tar -tzf`, independently of the scanner" },
964964
{ file: `${SCRIPTS}/smoke-installed.test.ts`, testName: "every publishable package's OWN exports map is fully covered -- no subpath silently skipped" },
965965
{ file: `${SCRIPTS}/smoke-installed.test.ts`, testName: "every target imports cleanly -- this is the exact check that would have caught review r1's two Criticals" },
966-
{ file: `${SCRIPTS}/build-packages.test.ts`, testName: "every entry emits BOTH a .js and a .d.ts, at the path its manifest condition names" },
966+
{ file: `${SCRIPTS}/build-packages.test.ts`, testName: "every entry emits BOTH a .js and a .d.ts, at the path its manifest condition names (bin-only packages emit none)" },
967967
],
968968
note: "The last citation is the fix wave's item 1 (R-7a-16 reversed): every manifest now points its `default` condition at a compiled emit, so `pack-smoke-node18` is a BLOCKING gate rather than the advisory carry it shipped as. The Node leg asserts what each package DECLARES through `engines` -- `@yanlinglabs/winter-provider-conformance` is Bun-only by construction (`Bun.serve` loopback fakes) and declares `engines.bun` alone.",
969969
},

scripts/release-pack.test.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,16 @@ describe("releasePack: the real, hermetic, mkdtemp-destined pack (WS-02 §9 Step
274274
expect([p.name, paths.filter((f) => /^package\/src\//.test(f))]).toEqual([p.name, []]);
275275
const source = discoverPublishablePackages().find((pkg) => pkg.name === p.name)!;
276276
if (isBinOnly(source)) {
277-
// P9a-3: the platform package ships a native BINARY, never `dist/` -- verified via `bin/`
278-
// instead, and it carries a LICENSE + README exactly like every other publishable package.
279-
expect([p.name, paths.some((f) => f.startsWith("package/bin/"))]).toEqual([p.name, true]);
277+
// P9a-3/P9a-5 MEASURED: the platform package ships a native BINARY, never `dist/` -- but
278+
// ONLY on a host that could have built it (darwin/arm64). On any other host (this repo's
279+
// own ubuntu `pack-smoke` jobs, and `bun test`'s run inside ci.yml's `build` job) the binary
280+
// is genuinely absent on disk, `assertDeclaredBinsExistOnMatchingHost` correctly does not
281+
// demand it there, and `pnpm pack` produces a tarball with NO `bin/` entry at all -- an empty
282+
// directory is never packed. Asserting presence unconditionally here is exactly the bug that
283+
// failed this test for real on ubuntu the first time this ran.
284+
const manifest = JSON.parse(readFileSync(source.packageJsonPath, "utf8")) as { os?: string[]; cpu?: string[] };
285+
const hostMatches = (manifest.os === undefined || manifest.os.includes(process.platform)) && (manifest.cpu === undefined || manifest.cpu.includes(process.arch));
286+
expect([p.name, hostMatches, paths.some((f) => f.startsWith("package/bin/"))]).toEqual([p.name, hostMatches, hostMatches]);
280287
} else {
281288
// ...and `dist/` really is there, so "no src" is not "nothing at all".
282289
expect([p.name, paths.some((f) => f.startsWith("package/dist/"))]).toEqual([p.name, true]);

scripts/smoke-installed.test.ts

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import { describe, test, expect, beforeAll, afterAll } from "bun:test";
1010
import { chmodSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
1111
import { tmpdir } from "node:os";
1212
import { join } from "node:path";
13-
import { discoverPublishablePackages } from "./release-pack.ts";
14-
import { assertInstalledTreeIsDistOnly, deriveImportTargets, runBinTarget, runSmoke, runtimesFor, type BinTarget, type SmokeResult } from "./smoke-installed.ts";
13+
import { discoverPublishablePackages, type PackedPackage } from "./release-pack.ts";
14+
import { assertInstalledTreeIsDistOnly, deriveImportTargets, installableOnThisHost, runBinTarget, runSmoke, runtimesFor, type BinTarget, type SmokeResult } from "./smoke-installed.ts";
1515

1616
// --- P7a fix wave (item 11, N-3): the pack+install legs are OPT-IN outside CI --------------------
1717
//
@@ -158,6 +158,39 @@ describe("runBinTarget (P9a-5)", () => {
158158
});
159159
});
160160

161+
// P9a-5 MEASURED: the real bug this exists for. `npm install <tarball-a> <tarball-b>` refuses the
162+
// WHOLE command with EBADPLATFORM the instant ONE explicitly-named tarball's os/cpu mismatches --
163+
// reproduced for real on ubuntu's `pack-smoke`/`pack-smoke-node18` jobs before this filter existed.
164+
describe("installableOnThisHost (P9a-5)", () => {
165+
const fake = (name: string): PackedPackage => ({ name, version: "0.0.4", tarballPath: `/tmp/${name}.tgz`, file: `${name}.tgz`, sha256: "x".repeat(64), size: 1 });
166+
167+
test("a bin-only package whose os/cpu MATCHES the given host is included", () => {
168+
const packages = [fake("@t/js-pkg"), fake("@t/bin-pkg")];
169+
const targets: BinTarget[] = [{ kind: "bin", package: "@t/bin-pkg", version: "0.0.4", bin: "/x/bin", os: ["darwin"], cpu: ["arm64"] }];
170+
const result = installableOnThisHost(packages, targets, "darwin", "arm64");
171+
expect(result.map((p) => p.name)).toEqual(["@t/js-pkg", "@t/bin-pkg"]);
172+
});
173+
174+
test("a bin-only package whose os/cpu MISMATCHES the given host is EXCLUDED -- the JS packages are not", () => {
175+
const packages = [fake("@t/js-pkg"), fake("@t/bin-pkg")];
176+
const targets: BinTarget[] = [{ kind: "bin", package: "@t/bin-pkg", version: "0.0.4", bin: "/x/bin", os: ["darwin"], cpu: ["arm64"] }];
177+
const result = installableOnThisHost(packages, targets, "linux", "x64");
178+
expect(result.map((p) => p.name)).toEqual(["@t/js-pkg"]);
179+
});
180+
181+
test("an os-only or cpu-only mismatch is excluded too -- both fields must agree, not just one", () => {
182+
const packages = [fake("@t/bin-pkg")];
183+
const targets: BinTarget[] = [{ kind: "bin", package: "@t/bin-pkg", version: "0.0.4", bin: "/x/bin", os: ["darwin"], cpu: ["arm64"] }];
184+
expect(installableOnThisHost(packages, targets, "darwin", "x64")).toEqual([]); // cpu mismatch alone
185+
expect(installableOnThisHost(packages, targets, "linux", "arm64")).toEqual([]); // os mismatch alone
186+
});
187+
188+
test("a package with no bin target at all (every JS package) is never excluded, regardless of host", () => {
189+
const packages = [fake("@t/js-pkg")];
190+
expect(installableOnThisHost(packages, [], "linux", "x64")).toEqual(packages);
191+
});
192+
});
193+
161194
describe.skipIf(!PACK_SMOKE_ENABLED)("runSmoke: the real pack -> install -> import cycle, under Bun (BLOCKING in ci.yml/release.yml)", () => {
162195
let result: SmokeResult;
163196
beforeAll(async () => {

scripts/smoke-installed.ts

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
2727
import { tmpdir } from "node:os";
2828
import { join } from "node:path";
29-
import { discoverPublishablePackages, releasePack, type PublishablePackage } from "./release-pack.ts";
29+
import { discoverPublishablePackages, releasePack, type PackedPackage, type PublishablePackage } from "./release-pack.ts";
3030

3131
export type SmokeRuntime = "node" | "bun";
3232

@@ -176,16 +176,50 @@ async function importUnder(runtime: SmokeRuntime, specifier: string, probeDir: s
176176
return { ok: exitCode === 0, output: (stdout + stderr).trim() };
177177
}
178178

179+
/**
180+
* Does `target`'s declared `os`/`cpu` match a host? Defaults to the CURRENT host; `platform`/`arch`
181+
* are injectable so `installableOnThisHost`'s own test can plant a mismatch without touching
182+
* `process.platform`/`process.arch` (which bun/node do not allow reassigning on some builds anyway).
183+
*/
184+
export function hostMatchesBinTarget(target: BinTarget, platform: string = process.platform, arch: string = process.arch): boolean {
185+
return (target.os === undefined || target.os.includes(platform)) && (target.cpu === undefined || target.cpu.includes(arch));
186+
}
187+
188+
/**
189+
* P9a-5 MEASURED (not assumed): which packed packages can be handed to `npm install` DIRECTLY, on
190+
* `platform`/`arch` (defaults to the current host).
191+
*
192+
* `bun install`'s own tolerance for a mismatched OPTIONAL dependency (M1: the package directory is
193+
* still created, `bin/` is empty) does NOT extend to plain `npm install <tarball-path>` -- npm
194+
* treats every EXPLICITLY-named command-line argument as a REQUIRED install target regardless of
195+
* what the wrapper's own `optionalDependencies` say about it, and refuses the WHOLE install with
196+
* `EBADPLATFORM` the instant one argument's `os`/`cpu` mismatches (measured on the real ubuntu
197+
* `pack-smoke`/`pack-smoke-node18` jobs the first time this ran: one mismatched tarball killed the
198+
* entire offline install, every OTHER package included, not just the platform one). So a mismatched
199+
* bin-only package is excluded from the install command line entirely -- its own check is answered
200+
* as a SKIP without ever attempting to install or spawn it, never a failed install of everything.
201+
*/
202+
export function installableOnThisHost(
203+
packages: readonly PackedPackage[],
204+
targets: readonly SmokeTarget[],
205+
platform: string = process.platform,
206+
arch: string = process.arch,
207+
): PackedPackage[] {
208+
const binTargetsByPackage = new Map(targets.filter((t): t is BinTarget => t.kind === "bin").map((t) => [t.package, t]));
209+
return packages.filter((p) => {
210+
const binTarget = binTargetsByPackage.get(p.name);
211+
return binTarget === undefined || hostMatchesBinTarget(binTarget, platform, arch);
212+
});
213+
}
214+
179215
/**
180216
* P9a-5: executes `<bin> --version` when the target's declared `os`/`cpu` matches the CURRENT host,
181217
* and asserts the printed line equals the package's own `version` exactly. On a mismatching host the
182218
* file cannot exist by construction (P9a-4), so this SKIPS with the exact printed reason rather than
183219
* attempting a spawn that could only ever fail with ENOENT for the wrong reason.
184220
*/
185221
export async function runBinTarget(target: BinTarget, binPath: string = target.bin): Promise<{ ok: boolean; output: string; skipped: boolean }> {
186-
const osOk = target.os === undefined || target.os.includes(process.platform);
187-
const cpuOk = target.cpu === undefined || target.cpu.includes(process.arch);
188-
if (!osOk || !cpuOk) {
222+
if (!hostMatchesBinTarget(target)) {
189223
const line = `smoke-installed: SKIP ${target.package} (bin-only; os/cpu mismatch on ${process.platform}/${process.arch})`;
190224
console.log(line);
191225
return { ok: true, output: line, skipped: true };
@@ -251,11 +285,13 @@ export async function runSmoke(opts: { runtimes?: readonly SmokeRuntime[] } = {}
251285
}
252286
const targets = deriveImportTargets();
253287

288+
const installable = installableOnThisHost(packed.packages, targets);
289+
254290
// Outside the monorepo on purpose: a fresh mkdtemp, no pnpm-workspace.yaml, no lockfile, no
255291
// committed .npmrc in scope -- the only thing that could make this succeed is the packed
256292
// tarballs themselves resolving each other correctly.
257293
writeFileSync(join(probeDir, "package.json"), JSON.stringify({ name: "winter-smoke-probe", private: true, version: "0.0.0" }, null, 2) + "\n");
258-
const install = Bun.spawnSync(["npm", "install", "--offline", ...packed.packages.map((p) => p.tarballPath)], { cwd: probeDir, stdout: "pipe", stderr: "pipe" });
294+
const install = Bun.spawnSync(["npm", "install", "--offline", ...installable.map((p) => p.tarballPath)], { cwd: probeDir, stdout: "pipe", stderr: "pipe" });
259295
if (install.exitCode !== 0) {
260296
throw new Error(`npm install --offline failed (exit ${install.exitCode}):\n${decode(install.stdout)}${decode(install.stderr)}`);
261297
}
@@ -266,7 +302,7 @@ export async function runSmoke(opts: { runtimes?: readonly SmokeRuntime[] } = {}
266302
// condition surviving here would send Bun to a `src/` path that is not on disk, which is the one
267303
// failure the source-condition design makes possible and the one no import test would attribute
268304
// correctly (it looks like a missing module, not a manifest that lies).
269-
const distOnly = assertInstalledTreeIsDistOnly(probeDir, packed.packages.map((p) => p.name));
305+
const distOnly = assertInstalledTreeIsDistOnly(probeDir, installable.map((p) => p.name));
270306
if (distOnly.length > 0) throw new Error(`the installed tree is not dist-only:\n${distOnly.join("\n")}`);
271307

272308
// P9a-5: bin targets run ONCE per `runSmoke()` call, independent of which `runtimes` were
@@ -276,6 +312,14 @@ export async function runSmoke(opts: { runtimes?: readonly SmokeRuntime[] } = {}
276312
// a non-matching host, and a real execution on a matching one (the new macOS job).
277313
for (const target of targets) {
278314
if (target.kind !== "bin") continue;
315+
if (!hostMatchesBinTarget(target)) {
316+
// Never installed above -- resolving its path or spawning it would fail for the WRONG
317+
// reason (a missing node_modules entry, not a deliberate platform mismatch).
318+
const line = `smoke-installed: SKIP ${target.package} (bin-only; os/cpu mismatch on ${process.platform}/${process.arch})`;
319+
console.log(line);
320+
results.push({ kind: "bin", package: target.package, ok: true, output: line, skipped: true });
321+
continue;
322+
}
279323
const binPath = resolveBinTargetPath(target, probeDir);
280324
const result = await runBinTarget(target, binPath);
281325
results.push({ kind: "bin", package: target.package, ok: result.ok, output: result.output, skipped: result.skipped });

0 commit comments

Comments
 (0)