91 lines
3.0 KiB
JavaScript
91 lines
3.0 KiB
JavaScript
import { spawnSync } from "node:child_process";
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
|
|
const archiveDir = process.env.PROJECTBRAIN_PROOF_ARCHIVE_DIR ?? "checkpoints/release-proof";
|
|
const allowStale = process.argv.includes("--allow-stale") || process.env.PROJECTBRAIN_PROOF_ALLOW_STALE === "1";
|
|
|
|
const run = (command, args) => spawnSync(command, args, {
|
|
encoding: "utf8",
|
|
shell: process.platform === "win32",
|
|
});
|
|
|
|
const getGitCommit = () => {
|
|
const result = run("git", ["rev-parse", "--short", "HEAD"]);
|
|
return result.status === 0 ? result.stdout.trim() : "unknown";
|
|
};
|
|
|
|
const parseField = (text, label) => {
|
|
const match = text.match(new RegExp(`^${label}:\\s*(.+)$`, "m"));
|
|
return match?.[1]?.trim() ?? "unknown";
|
|
};
|
|
|
|
const displayPath = (filePath) => filePath.split(path.sep).join("/");
|
|
|
|
const parseProof = (filePath) => {
|
|
const text = fs.readFileSync(filePath, "utf8");
|
|
return {
|
|
filePath,
|
|
displayPath: displayPath(filePath),
|
|
fileName: path.basename(filePath),
|
|
generated: parseField(text, "Generated"),
|
|
commit: parseField(text, "Commit"),
|
|
project: parseField(text, "Project"),
|
|
verdict: parseField(text, "Verdict"),
|
|
smokeExecution: text.match(/^- Smoke execution:\s*(.+)$/m)?.[1]?.trim() ?? "unknown",
|
|
};
|
|
};
|
|
|
|
const listProofFiles = () => {
|
|
if (!fs.existsSync(archiveDir)) return [];
|
|
|
|
return fs.readdirSync(archiveDir)
|
|
.filter((fileName) => fileName.endsWith(".md"))
|
|
.map((fileName) => path.join(archiveDir, fileName))
|
|
.filter((filePath) => fs.statSync(filePath).isFile());
|
|
};
|
|
|
|
const currentCommit = getGitCommit();
|
|
const proofs = listProofFiles()
|
|
.map(parseProof)
|
|
.sort((a, b) => Date.parse(b.generated) - Date.parse(a.generated) || b.fileName.localeCompare(a.fileName));
|
|
const latestPassing = proofs.find((proof) => proof.verdict === "PASS");
|
|
const freshness = !latestPassing
|
|
? "missing"
|
|
: latestPassing.commit === currentCommit
|
|
? "current"
|
|
: "stale";
|
|
|
|
const lines = [
|
|
"# ProjectBrain Release Proof Freshness",
|
|
"",
|
|
`Archive: ${archiveDir}`,
|
|
`Current commit: ${currentCommit}`,
|
|
`Latest passing proof: ${latestPassing ? latestPassing.displayPath : "none"}`,
|
|
`Proof commit: ${latestPassing?.commit ?? "none"}`,
|
|
`Freshness: ${freshness}`,
|
|
`Strict mode: ${allowStale ? "disabled" : "enabled"}`,
|
|
"",
|
|
];
|
|
|
|
if (latestPassing) {
|
|
lines.push("| Generated | Verdict | Project | Smoke | File |");
|
|
lines.push("| --- | --- | --- | --- | --- |");
|
|
lines.push(`| ${latestPassing.generated} | ${latestPassing.verdict} | ${latestPassing.project} | ${latestPassing.smokeExecution} | ${latestPassing.displayPath} |`);
|
|
lines.push("");
|
|
}
|
|
|
|
if (freshness !== "current") {
|
|
lines.push("Create a fresh passing proof for the current commit with:");
|
|
lines.push("");
|
|
lines.push("```bash");
|
|
lines.push("PROJECTBRAIN_SMOKE_URL=http://127.0.0.1:1209 PROJECTBRAIN_PROOF_RUN_SMOKES=1 PROJECTBRAIN_PROOF_WRITE=1 pnpm run release:proof-report");
|
|
lines.push("```");
|
|
}
|
|
|
|
console.log(lines.join("\n"));
|
|
|
|
if (!allowStale && freshness !== "current") {
|
|
process.exitCode = 1;
|
|
}
|