fix: harden repository coverage evidence

This commit is contained in:
DongHyeonka
2026-08-02 08:20:25 +09:00
parent 5a73f7a1b5
commit 67cd37659d
6 changed files with 1178 additions and 509 deletions
+34 -46
View File
@@ -1,6 +1,9 @@
import { mkdir, readFile, writeFile } from "node:fs/promises";
import path from "node:path";
import {
readRiskCoverageInput,
writeRiskCoverageArtifactAtomic,
} from "./lib/risk-coverage-files.ts";
import {
buildProductionModuleInventory,
evaluateRiskCoverage,
@@ -18,71 +21,56 @@ function requiredArgument(name: string, fallback: string): string {
return value;
}
function parseChangedFiles(value: unknown): readonly string[] {
if (
!Array.isArray(value) ||
value.some((entry) => typeof entry !== "string") ||
new Set(value).size !== value.length
) {
throw new TypeError("changed files input must be an array of unique paths");
}
return Object.freeze([...value] as string[]);
}
const repositoryRoot = path.resolve(
requiredArgument("--repository-root", process.cwd()),
);
const policyPath = requiredArgument(
"--policy",
"config/testing/risk-coverage.json",
);
const summaryPath = requiredArgument(
"--summary",
"artifacts/tests/coverage/coverage-summary.json",
);
const policyInput = await readRiskCoverageInput({
repositoryRoot,
relativePath: requiredArgument(
"--policy",
"config/testing/risk-coverage.json",
),
label: "policy",
});
const summaryInput = await readRiskCoverageInput({
repositoryRoot,
relativePath: requiredArgument(
"--summary",
"artifacts/tests/coverage/coverage-summary.json",
),
label: "summary",
});
const artifactPath = requiredArgument(
"--artifact",
"artifacts/quality/risk-coverage.json",
);
const changedFilesPath = argumentValue("--changed-files");
const policy = parseRepositoryRiskCoveragePolicy(
JSON.parse(await readFile(path.resolve(repositoryRoot, policyPath), "utf8")) as unknown,
JSON.parse(policyInput.text) as unknown,
);
const inventory = await buildProductionModuleInventory({
repositoryRoot,
generatedPaths: policy.generatedPaths,
});
const changedFiles = changedFilesPath
? parseChangedFiles(
JSON.parse(
await readFile(path.resolve(repositoryRoot, changedFilesPath), "utf8"),
) as unknown,
)
: [];
const result = evaluateRiskCoverage({
repositoryRoot,
inventory,
policy,
summary: JSON.parse(
await readFile(path.resolve(repositoryRoot, summaryPath), "utf8"),
) as unknown,
changedFiles,
summary: JSON.parse(summaryInput.text) as unknown,
});
await writeRiskCoverageArtifactAtomic({
repositoryRoot,
relativePath: artifactPath,
inputPaths: [policyInput.relativePath, summaryInput.relativePath],
value: {
schemaVersion: 2,
policy: policyInput.relativePath,
summary: summaryInput.relativePath,
...result,
},
});
const artifact = {
schemaVersion: 2,
policy: policyPath,
summary: summaryPath,
changedFiles: changedFilesPath ?? null,
...result,
};
const resolvedArtifactPath = path.resolve(repositoryRoot, artifactPath);
await mkdir(path.dirname(resolvedArtifactPath), { recursive: true });
await writeFile(resolvedArtifactPath, `${JSON.stringify(artifact, null, 2)}\n`);
if (result.failures.length > 0) {
process.stderr.write(
`Risk coverage failed:\n- ${result.failures.join("\n- ")}\n`,
);
process.stderr.write(`Risk coverage failed:\n- ${result.failures.join("\n- ")}\n`);
process.exit(1);
}
process.stdout.write(