Files
cnc_wams/web-rtcp-5axis-xyzbc-trt-sim-plan/tests/node/verify_static_release_reproducibility.mjs
2026-07-10 21:26:42 -04:00

65 lines
2.3 KiB
JavaScript

import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import { createHash } from "node:crypto";
import { lstatSync, readFileSync, readdirSync, readlinkSync } from "node:fs";
import { dirname, relative, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const webRoot = resolve(dirname(fileURLToPath(import.meta.url)), "../..");
const appRoot = resolve(webRoot, "app");
const distRoot = resolve(appRoot, "dist");
function digestTree(root) {
const entries = [];
function walk(path) {
for (const name of readdirSync(path).sort()) {
const entryPath = resolve(path, name);
const stat = lstatSync(entryPath);
const relativePath = relative(root, entryPath).split("\\").join("/");
if (stat.isDirectory()) {
entries.push({ type: "directory", path: relativePath, mode: stat.mode & 0o777 });
walk(entryPath);
} else if (stat.isSymbolicLink()) {
entries.push({
type: "symlink",
path: relativePath,
mode: stat.mode & 0o777,
target: readlinkSync(entryPath),
});
} else if (stat.isFile()) {
entries.push({
type: "file",
path: relativePath,
mode: stat.mode & 0o777,
sha256: createHash("sha256").update(readFileSync(entryPath)).digest("hex"),
});
} else {
assert.fail(`unsupported static release entry: ${relativePath}`);
}
}
}
walk(root);
return {
entryCount: entries.length,
fileCount: entries.filter(({ type }) => type === "file").length,
digest: createHash("sha256").update(JSON.stringify(entries)).digest("hex"),
};
}
const first = digestTree(distRoot);
const build = spawnSync("npm", ["run", "build"], {
cwd: appRoot,
encoding: "utf8",
stdio: ["ignore", "pipe", "pipe"],
});
process.stdout.write(build.stdout || "");
process.stderr.write(build.stderr || "");
assert.equal(build.status, 0, `second static build failed with status ${build.status}`);
const second = digestTree(distRoot);
assert.deepEqual(second, first);
console.log(`static_release_entry_count=${second.entryCount}`);
console.log(`static_release_file_count=${second.fileCount}`);
console.log(`static_release_tree_sha256=${second.digest}`);
console.log("static_release_reproducibility=ok");