Files
fusion/scripts/__tests__/dockerfile-workspace-manifests.test.mjs
gsxdsm aedee4b823 feat(docker): ship ripgrep in the image
The coding agents Fusion drives reach for `rg` as their primary search tool. It
was absent from the image, so inside a container they silently fall back to
slower or partial search while working fine on a developer machine that has it
installed. Operator asked for it by default.

Installed alongside git and ca-certificates in the runner stage, and covered by
the same runner-stage guard so it cannot quietly drop out again.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 22:43:59 -07:00

135 lines
5.8 KiB
JavaScript

import test from "node:test";
import assert from "node:assert/strict";
import { globSync, readFileSync } from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import YAML from "yaml";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const repoRoot = path.resolve(__dirname, "../..");
function normalizeDockerSource(source) {
return source.replace(/^\.\//, "").replace(/\/$/, "");
}
function readWorkspacePackageManifestPaths(root = repoRoot) {
const workspacePath = path.join(root, "pnpm-workspace.yaml");
const workspace = YAML.parse(readFileSync(workspacePath, "utf8"));
const entries = Array.isArray(workspace?.packages) ? workspace.packages : [];
const manifestPaths = new Set();
for (const entry of entries) {
if (typeof entry !== "string" || entry.startsWith("!")) {
continue;
}
for (const manifest of globSync(`${entry.replace(/\/$/, "")}/package.json`, {
cwd: root,
nodir: true,
})) {
manifestPaths.add(manifest.split(path.sep).join("/"));
}
}
return manifestPaths;
}
function readBuilderPreInstallCopySources(dockerfile) {
const builderStart = dockerfile.match(/^FROM\s+.*\s+AS\s+builder\s*$/im);
assert.ok(builderStart?.index !== undefined, "Dockerfile must define a builder stage");
const afterBuilder = dockerfile.slice(builderStart.index + builderStart[0].length);
const nextStage = afterBuilder.search(/^FROM\s+/im);
const builderStage = nextStage === -1 ? afterBuilder : afterBuilder.slice(0, nextStage);
const install = builderStage.match(/RUN\s+pnpm\s+install\s+--frozen-lockfile\b/);
assert.ok(install?.index !== undefined, "builder stage must run pnpm install --frozen-lockfile");
const copied = [];
for (const match of builderStage.slice(0, install.index).matchAll(/^COPY\s+(?:--\S+\s+)*(.*?)\s+\S+\s*$/gm)) {
const sources = match[1].trim().split(/\s+/).map(normalizeDockerSource);
copied.push(...sources);
}
return copied;
}
function findMissingWorkspaceManifests(manifests, copySources) {
return [...manifests].filter((manifest) => !copySources.some((source) => (
source === manifest || source === "." || manifest.startsWith(`${source}/`)
))).sort();
}
function readDockerfileCopiedManifestPaths() {
const dockerfile = readFileSync(path.join(repoRoot, "Dockerfile"), "utf8");
const copied = readBuilderPreInstallCopySources(dockerfile);
return { copied, dockerfile };
}
test("Dockerfile builder pre-install copies cover every current workspace manifest", () => {
const expected = readWorkspacePackageManifestPaths();
const { copied } = readDockerfileCopiedManifestPaths();
assert.deepEqual(findMissingWorkspaceManifests(expected, copied), []);
assert.equal(new Set(copied).size, copied.length, "builder pre-install COPY sources must not be duplicated");
});
test("coverage rejects a selected plugin omitted before frozen install", () => {
const expected = readWorkspacePackageManifestPaths();
const omitted = [...expected].sort().find((manifest) => manifest.startsWith("plugins/"));
assert.ok(omitted, "workspace fixture must include a plugin manifest");
const completeSources = [...expected];
const incompleteSources = completeSources.filter((source) => source !== omitted);
assert.deepEqual(findMissingWorkspaceManifests(expected, incompleteSources), [omitted]);
});
test("coverage ignores post-install and runner copies while tolerating removed paths", () => {
const expected = readWorkspacePackageManifestPaths();
const omitted = [...expected].sort().find((manifest) => manifest.startsWith("plugins/"));
assert.ok(omitted, "workspace fixture must include a plugin manifest");
const builderCopies = [...expected]
.filter((manifest) => manifest !== omitted)
.map((manifest) => `COPY ${manifest} ./${manifest}`)
.join("\n");
const dockerfile = `FROM node:22-slim AS builder\n${builderCopies}\nRUN pnpm install --frozen-lockfile\nCOPY ${omitted} ./${omitted}\nFROM node:22-slim AS runner\nCOPY ${omitted} ./${omitted}`;
const copied = readBuilderPreInstallCopySources(dockerfile);
assert.deepEqual(findMissingWorkspaceManifests(expected, copied), [omitted]);
assert.deepEqual(
findMissingWorkspaceManifests(expected, [...expected, "plugins/not-in-workspace/package.json"]),
[],
"removed or nonexistent COPY paths must not affect selected workspace coverage",
);
});
/*
FNXC:DockerRun 2026-08-18-05:35:
The runner stage MUST install ca-certificates. The slim base ships none, and git verifies TLS
against the system store, so without it every HTTPS clone dies with "server certificate
verification failed. CAfile: none CRLfile: none" and project setup is impossible in Docker.
This regressed unnoticed because Node carries its OWN bundled CA store: the dashboard, model APIs
and OAuth token exchanges all worked, so nothing looked wrong until the first clone. Nothing else
in the image exercises the system trust store, which is exactly why it needs a guard rather than
relying on someone noticing.
*/
test("runner stage installs ca-certificates alongside git", () => {
const dockerfile = readFileSync(path.join(repoRoot, "Dockerfile"), "utf8");
const runnerStage = dockerfile.slice(dockerfile.indexOf("FROM node:22-slim AS runner"));
assert.ok(runnerStage.length > 0, "runner stage must exist");
const aptInstall = runnerStage.match(/apt-get install[^\n]*(?:\\\n[^\n]*)*/)?.[0] ?? "";
assert.match(aptInstall, /\bgit\b/, "runner stage must install git");
assert.match(
aptInstall,
/\bca-certificates\b/,
"runner stage must install ca-certificates — git cannot verify HTTPS remotes without a system CA bundle",
);
assert.match(
aptInstall,
/\bripgrep\b/,
"runner stage must install ripgrep — the coding agents Fusion drives use `rg` as their primary search tool",
);
});