fix: harden CI evidence and removal contracts
This commit is contained in:
@@ -1,17 +1,23 @@
|
||||
import { spawnSync } from "node:child_process";
|
||||
import {
|
||||
cp,
|
||||
mkdir,
|
||||
readFile,
|
||||
readdir,
|
||||
rm,
|
||||
symlink,
|
||||
writeFile,
|
||||
} from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
import {
|
||||
filesBelow,
|
||||
prepareRemovalFixture,
|
||||
pruneRemovalFixtureCiContract,
|
||||
pruneScriptOrchestration,
|
||||
regenerateRemovalFixtureWorkflow,
|
||||
requireRemovalFixtureEnvironment,
|
||||
runRemovalFixturePnpm,
|
||||
} from "./lib/removal-fixture.ts";
|
||||
|
||||
const fixtureRoot = path.resolve(".tmp/optional-recipe-removal");
|
||||
const pnpmCli = requireEnvironment("npm_execpath");
|
||||
const pnpmCli = requireRemovalFixtureEnvironment("npm_execpath");
|
||||
const copyTargets = [
|
||||
"src",
|
||||
"tests",
|
||||
@@ -44,51 +50,55 @@ const copyTargets = [
|
||||
".nvmrc",
|
||||
];
|
||||
|
||||
function requireEnvironment(name: string): string {
|
||||
const value = process.env[name];
|
||||
if (!value) {
|
||||
throw new Error(`${name} is required to run removal verification`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function runPnpm(script: string): boolean {
|
||||
return (
|
||||
spawnSync(process.execPath, [pnpmCli, script], {
|
||||
cwd: fixtureRoot,
|
||||
stdio: "inherit",
|
||||
}).status === 0
|
||||
);
|
||||
return runRemovalFixturePnpm(fixtureRoot, pnpmCli, script);
|
||||
}
|
||||
|
||||
async function filesBelow(directory: string): Promise<string[]> {
|
||||
const entries = await readdir(directory, { withFileTypes: true });
|
||||
const groups = await Promise.all(
|
||||
entries.map((entry) => {
|
||||
const target = path.join(directory, entry.name);
|
||||
return entry.isDirectory() ? filesBelow(target) : [target];
|
||||
}),
|
||||
);
|
||||
return groups.flat();
|
||||
await prepareRemovalFixture(fixtureRoot, copyTargets);
|
||||
for (const rootOnlyTest of [
|
||||
"tests/unit/ci-workflow-generation.test.ts",
|
||||
"tests/unit/__snapshots__/ci-workflow-generation.test.ts.snap",
|
||||
]) {
|
||||
await rm(path.join(fixtureRoot, rootOnlyTest), { force: true });
|
||||
}
|
||||
|
||||
await rm(fixtureRoot, { recursive: true, force: true });
|
||||
await mkdir(fixtureRoot, { recursive: true });
|
||||
for (const target of copyTargets) {
|
||||
await cp(target, path.join(fixtureRoot, target), { recursive: true });
|
||||
}
|
||||
await symlink(path.resolve("node_modules"), path.join(fixtureRoot, "node_modules"), "dir");
|
||||
await rm(path.join(fixtureRoot, "recipes"), { recursive: true, force: true });
|
||||
await rm(path.join(fixtureRoot, "tests/recipes"), {
|
||||
recursive: true,
|
||||
force: true,
|
||||
});
|
||||
|
||||
const removedCiScripts = new Set([
|
||||
"check:types:recipes",
|
||||
"test:recipes",
|
||||
"check:optional-recipes",
|
||||
"check:optional-recipes:source",
|
||||
"check:optional-recipe-fixtures",
|
||||
"test:optional-recipe-removal",
|
||||
]);
|
||||
const fixturePackagePath = path.join(fixtureRoot, "package.json");
|
||||
const fixturePackage = JSON.parse(await readFile(fixturePackagePath, "utf8")) as {
|
||||
scripts: Record<string, string>;
|
||||
};
|
||||
pruneScriptOrchestration(fixturePackage.scripts, "check:types", removedCiScripts);
|
||||
pruneScriptOrchestration(fixturePackage.scripts, "test:all", removedCiScripts);
|
||||
await writeFile(fixturePackagePath, `${JSON.stringify(fixturePackage, null, 2)}\n`);
|
||||
await pruneRemovalFixtureCiContract({
|
||||
root: fixtureRoot,
|
||||
removedScripts: removedCiScripts,
|
||||
removedEvidencePathFragments: [
|
||||
"optional-recipes",
|
||||
"optional-recipe-fixtures",
|
||||
"optional-recipe-removal",
|
||||
],
|
||||
});
|
||||
await regenerateRemovalFixtureWorkflow(fixtureRoot);
|
||||
|
||||
const checks: Array<[string, boolean]> = [
|
||||
["typecheck", runPnpm("check:types")],
|
||||
["architecture", runPnpm("check:architecture")],
|
||||
["test", runPnpm("test:all")],
|
||||
["build", runPnpm("build")],
|
||||
["ci-contract", runPnpm("check:ci")],
|
||||
];
|
||||
const residue: string[] = [];
|
||||
for (const file of await filesBelow(path.join(fixtureRoot, "dist"))) {
|
||||
|
||||
Reference in New Issue
Block a user