Files
rea/scripts/lib/release-package-install.mjs

96 lines
2.8 KiB
JavaScript

import { mkdir, writeFile } from "node:fs/promises";
import { join, resolve } from "node:path";
import { execNpm } from "./npm-command.mjs";
/** Install the selected archive or registry specifier before any protocol deadline. */
export async function installCanaryPackage(specifier, workspace, environment) {
const prefix = join(workspace, "installed");
await mkdir(prefix, { recursive: true });
await writeFile(
join(prefix, "package.json"),
JSON.stringify({
name: "rea-release-consumer-check",
version: "0.0.0",
private: true,
}) + "\n",
{ flag: "wx", mode: 0o600 },
);
await execNpm(
[
"install",
"--ignore-scripts",
"--save-exact",
"--package-lock=true",
"--no-audit",
"--no-fund",
"--prefix",
prefix,
specifier,
],
{ cwd: workspace, env: environment, maxBuffer: 16 * 1024 * 1024 },
);
return {
directory: prefix,
packageRoot: join(prefix, "node_modules", "rea-agents"),
};
}
export const consumerSecurityOptions = {
"dependency-security": { type: "string" },
"dependency-source": { type: "string" },
"dependency-source-sha": { type: "string" },
};
/** The source that owns a release may differ from the controller's checkout. */
export function consumerSecurityContext(
values,
directory = process.cwd(),
checkoutSha = process.env.GITHUB_SHA,
) {
const evidenceDirectory = values["dependency-security"];
const selectedSource = values["dependency-source"],
selectedSha = values["dependency-source-sha"];
if (
(selectedSource === undefined) !== (selectedSha === undefined) ||
(selectedSource !== undefined && evidenceDirectory === undefined)
)
throw new Error(
"Dependency source overrides require both source directory and SHA with security evidence enabled",
);
if (evidenceDirectory === undefined) return null;
const sourceSha = selectedSha ?? checkoutSha ?? null;
if (sourceSha !== null && !/^[a-f0-9]{40}$/u.test(sourceSha))
throw new Error("Dependency source SHA must be a full commit identity");
return {
evidenceDirectory,
referenceLockfile: join(
resolve(directory, selectedSource ?? "."),
"package-lock.json",
),
sourceSha,
};
}
export async function verifyCanaryDependencies(
installation,
context,
version,
environment,
qualifiedTarball = null,
) {
if (context === null) return;
const { checkDependencySecurity } = await import("./dependency-security.mjs");
const report = await checkDependencySecurity({
...context,
directory: installation.directory,
mode: "consumer",
expectedVersion: version,
environment,
qualifiedTarball,
});
if (!report.checks_passed)
throw new Error(
`Consumer dependency checks failed: ${report.evidence_directory}`,
);
}