import { readFile } from "node:fs/promises"; import { captureCiCandidateArchive, withVerifiedCapturedCandidate, } from "./lib/ci-candidate-archive.ts"; import { verifyArchivedLocalEvidence } from "./lib/local-release-evidence.ts"; import { RELEASE_CANDIDATE_MANIFEST_PATH, releaseCandidateManifestSchema, } from "./lib/release-candidate.ts"; const argument = (name: string): string | undefined => { const index = process.argv.indexOf(name); if (index < 0) return undefined; const value = process.argv[index + 1]; if (!value || value.startsWith("--")) { throw new TypeError(`${name} requires a value`); } return value; }; const archivePath = argument("--archive"); const expectedSha256 = argument("--sha256"); if (Boolean(archivePath) !== Boolean(expectedSha256)) { throw new TypeError("--archive and --sha256 must be supplied together"); } const result = archivePath && expectedSha256 ? await withVerifiedCapturedCandidate({ captured: await captureCiCandidateArchive({ archivePath, expectedSha256 }), verify: ({ extractionRoot, manifest }) => verifyArchivedLocalEvidence({ extractionRoot, expectedManifest: manifest }), }) : await verifyCheckoutEvidence(); if (result.status !== "PASS") { process.stderr.write( `Archived local evidence verification failed:\n- ${result.failures.join("\n- ")}\n`, ); process.exit(1); } process.stdout.write("Archived local evidence verification: PASS\n"); async function verifyCheckoutEvidence() { const candidate = releaseCandidateManifestSchema.parse( JSON.parse(await readFile(RELEASE_CANDIDATE_MANIFEST_PATH, "utf8")), ); return verifyArchivedLocalEvidence({ extractionRoot: process.cwd(), expectedManifest: candidate, }); }