Files
scriptc/packages/cli/test/runtime-pack.test.ts
Chris Tate 64b2a285d5 feat(runtime): ship precompiled macOS artifacts (#248)
* feat(runtime): ship precompiled macOS artifacts

- Add a versioned macOS arm64 runtime pack with deterministic feature selection and artifact verification.
- Link LLVM helper objects against release-built runtime and vendor inputs without compiling user-machine C.
- Wire package publishing, cache validation, documentation, and full-gate coverage for the new path.

* fix(runtime): harden precompiled artifact handling

* fix(runtime): make precompiled artifacts reproducible

* fix(runtime): reject opaque linkers from executable cache

* fix(runtime): normalize precompiled archive metadata

* fix(runtime): harden precompiled artifact caching

* fix(runtime): close executable cache link race

* fix(runtime): stage verified pack artifacts

* fix(runtime): bracket helper cache inputs

* fix(runtime): preserve executable link identity

* fix(runtime): trace selected linker dependencies
2026-08-28 09:29:21 -05:00

68 lines
2.9 KiB
TypeScript

import { execFile } from "node:child_process";
import { createRequire } from "node:module";
import { chmod, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
import { release as osRelease, tmpdir } from "node:os";
import { basename, dirname, join } from "node:path";
import { promisify } from "node:util";
import { afterEach, describe, expect, test } from "vitest";
const execFileAsync = promisify(execFile);
const require = createRequire(import.meta.url);
const repoRoot = join(import.meta.dirname, "../../..");
const cliEntry = join(repoRoot, "packages/cli/src/main.ts");
const tsxLoader = join(dirname(require.resolve("tsx/package.json")), "dist/loader.mjs");
const supported = process.platform === "darwin" && process.arch === "arm64" &&
Number.parseInt(osRelease().split(".", 1)[0] ?? "", 10) >= 24;
const dirs: string[] = [];
afterEach(async () => {
await Promise.all(dirs.splice(0).map((dir) => rm(dir, { recursive: true, force: true })));
});
describe.runIf(supported)("precompiled runtime executable builds", () => {
test("ordinary LLVM executables invoke the linker but no C compiler mode", async () => {
const dir = await mkdtemp(join(tmpdir(), "scriptc-runtime-pack-cli-"));
dirs.push(dir);
const entry = join(dir, "main.ts");
const output = join(dir, "program");
const wrapper = join(dir, "linker");
const log = join(dir, "linker.json");
await writeFile(entry, 'console.log("precompiled runtime");\n');
await writeFile(wrapper, [
"#!/bin/sh",
`node -e 'require("fs").writeFileSync(process.argv[1], JSON.stringify(process.argv.slice(2)))' '${log}' \"$@\"`,
"exec clang \"$@\"",
"",
].join("\n"));
await chmod(wrapper, 0o755);
const cliArgs = [
"--import", tsxLoader, cliEntry, "build", entry, "-o", output,
];
const env = {
...process.env,
SCRIPTC_NO_CACHE: "1",
SCRIPTC_LINKER: wrapper,
};
await execFileAsync(process.execPath, cliArgs, {
env: {
...env,
},
});
const args = JSON.parse(await readFile(log, "utf8")) as string[];
expect(args).not.toContain("-c");
expect(args.some((arg) => arg.endsWith(".c") || arg.endsWith(".ll"))).toBe(false);
expect(args.some((arg) =>
arg.includes("scriptc-runtime-pack-link-") && arg.includes("/artifacts/")
)).toBe(true);
expect(args.some((arg) => arg.includes("runtime-darwin-arm64/artifacts"))).toBe(false);
await expect(execFileAsync(output, [], { encoding: "utf8" }))
.resolves.toMatchObject({ stdout: "precompiled runtime\n" });
const firstExecutable = await readFile(output);
const signature = await execFileAsync("codesign", ["-dvvv", output], { encoding: "utf8" });
expect(signature.stderr).toContain(`Identifier=${basename(output)}`);
await execFileAsync(process.execPath, cliArgs, { env });
expect(await readFile(output)).toEqual(firstExecutable);
});
});