import { execFile } from "node:child_process"; import { readFile } from "node:fs/promises"; import path from "node:path"; import { promisify } from "node:util"; const execFileAsync = promisify(execFile); const root = path.resolve(import.meta.dirname, ".."); const pkg = JSON.parse(await readFile(path.join(root, "package.json"), "utf8")); const signedRelease = process.env.FORGEFLOW_SIGNED_RELEASE === "1"; const expectedPublisher = String(process.env.FORGEFLOW_EXPECTED_PUBLISHER || "").trim(); if (signedRelease && !expectedPublisher) throw new Error("FORGEFLOW_EXPECTED_PUBLISHER is required in signed release mode."); const artifacts = ["Setup", "Portable"].map((kind) => path.join(root, "dist", `ForgeFlow-${kind}-${pkg.version}-win-x64.exe`)); for (const artifact of artifacts) { const script = `$s=Get-AuthenticodeSignature -LiteralPath $args[0]; [pscustomobject]@{Status=$s.Status.ToString();Subject=$s.SignerCertificate.Subject;Thumbprint=$s.SignerCertificate.Thumbprint;TimestampSubject=$s.TimeStamperCertificate.Subject}|ConvertTo-Json -Compress`; const { stdout } = await execFileAsync("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", script, artifact], { windowsHide: true }); const result = JSON.parse(stdout.trim()); const valid = result.Status === "Valid" && Boolean(result.TimestampSubject); const publisherMatches = !expectedPublisher || String(result.Subject || "").includes(expectedPublisher); if (signedRelease && (!valid || !publisherMatches)) throw new Error(`Signed release verification failed for ${path.basename(artifact)}: status=${result.Status}, publisher=${result.Subject || "missing"}, timestamp=${result.TimestampSubject || "missing"}.`); console.log(`${path.basename(artifact)}: ${valid && publisherMatches ? "valid signed artifact" : "unsigned development artifact"}`); }