Complete V1 RC deployment capability gates
This commit is contained in:
103
tools/web/run-v1-acceptance.mjs
Normal file
103
tools/web/run-v1-acceptance.mjs
Normal file
@@ -0,0 +1,103 @@
|
||||
import fs from "node:fs";
|
||||
import { spawnSync } from "node:child_process";
|
||||
import {
|
||||
evidencePath,
|
||||
expectedEvidenceIdentity,
|
||||
root,
|
||||
sha256,
|
||||
} from "./v1-acceptance-lib.mjs";
|
||||
|
||||
const { ledgerSha256, packageSha256, plan, toolSourceSha256 } = expectedEvidenceIdentity();
|
||||
const basePort = Number.parseInt(process.env.WEB_ACCEPTANCE_PORT ?? "5400", 10);
|
||||
if (!Number.isInteger(basePort) || basePort < 1024 || basePort > 65000 - plan.entries.length) {
|
||||
throw new Error(`WEB_ACCEPTANCE_PORT must leave ${plan.entries.length} sequential ports available`);
|
||||
}
|
||||
|
||||
function capture(command, args) {
|
||||
const result = spawnSync(command, args, {
|
||||
cwd: root,
|
||||
encoding: "utf8",
|
||||
env: { ...process.env, FORCE_COLOR: "0", NO_COLOR: "1" },
|
||||
maxBuffer: 16 * 1024 * 1024,
|
||||
});
|
||||
return `${result.stdout ?? ""}\n${result.stderr ?? ""}`.trim();
|
||||
}
|
||||
|
||||
const blenderBin = process.env.BLENDER_BIN ?? "build_blender_5.2.0/bin/blender";
|
||||
const blenderArchiveSha256 = process.env.BLENDER_ARCHIVE_SHA256 ?? "";
|
||||
if (blenderArchiveSha256 && !/^[a-f0-9]{64}$/.test(blenderArchiveSha256)) {
|
||||
throw new Error("BLENDER_ARCHIVE_SHA256 must be a lowercase SHA-256");
|
||||
}
|
||||
const environment = {
|
||||
node: process.version,
|
||||
npm: capture("npm", ["--version"]).split(/\r?\n/)[0],
|
||||
chromium: capture(process.env.CHROME_PATH ?? "/home/mes123456/.local/bin/google-chrome", ["--version"]).split(/\r?\n/)[0],
|
||||
blenderBin: process.env.BLENDER_BIN ? "BLENDER_BIN" : blenderBin,
|
||||
blenderExecutableSha256: fs.existsSync(blenderBin) ? sha256(fs.readFileSync(blenderBin)) : "unavailable",
|
||||
blenderArchiveSha256: blenderArchiveSha256 || "unavailable",
|
||||
blender: capture(blenderBin, [
|
||||
"--background",
|
||||
"--factory-startup",
|
||||
"--python-expr",
|
||||
"import bpy; print('ACCEPTANCE_BLENDER=' + bpy.app.version_string + ';USD=' + str(bpy.app.build_options.usd))",
|
||||
]).split(/\r?\n/).filter((line) => line.includes("ACCEPTANCE_BLENDER=")).at(-1) ?? "unavailable",
|
||||
};
|
||||
|
||||
const results = [];
|
||||
for (const [index, entry] of plan.entries.entries()) {
|
||||
const started = Date.now();
|
||||
process.stdout.write(`[${index + 1}/${plan.entries.length}] ${entry.token}\n`);
|
||||
const result = spawnSync("npm", ["--prefix", "web", "run", entry.script, ...entry.args], {
|
||||
cwd: root,
|
||||
encoding: "utf8",
|
||||
env: {
|
||||
...process.env,
|
||||
FORCE_COLOR: "0",
|
||||
NO_COLOR: "1",
|
||||
WEB_TEST_PORT: String(basePort + index),
|
||||
},
|
||||
maxBuffer: 32 * 1024 * 1024,
|
||||
});
|
||||
const output = `${result.stdout ?? ""}\n${result.stderr ?? ""}`.trim();
|
||||
const storedOutput = output.slice(-4096) || `${entry.token} produced no output`;
|
||||
const exitCode = result.status ?? 1;
|
||||
results.push({
|
||||
token: entry.token,
|
||||
familyIds: entry.familyIds,
|
||||
command: entry.command,
|
||||
exitCode,
|
||||
durationMs: Date.now() - started,
|
||||
outputSha256: sha256(storedOutput),
|
||||
output: storedOutput,
|
||||
});
|
||||
process.stdout.write(` exit=${exitCode} durationMs=${results.at(-1).durationMs}\n`);
|
||||
}
|
||||
|
||||
const manifest = {
|
||||
schemaVersion: 1,
|
||||
source: "docs/status/parity-ledger.json",
|
||||
sourceSha256: ledgerSha256,
|
||||
package: "web/package.json",
|
||||
packageSha256,
|
||||
toolSourceSha256,
|
||||
generatedAt: new Date().toISOString(),
|
||||
environment,
|
||||
summary: {
|
||||
families: plan.familyCount,
|
||||
declarations: plan.declarationCount,
|
||||
unique: plan.uniqueCount,
|
||||
passed: results.filter((result) => result.exitCode === 0).length,
|
||||
failed: results.filter((result) => result.exitCode !== 0).length,
|
||||
},
|
||||
results,
|
||||
};
|
||||
fs.writeFileSync(evidencePath, `${JSON.stringify(manifest, null, 2)}\n`);
|
||||
|
||||
const failed = results.filter((result) => result.exitCode !== 0);
|
||||
process.stdout.write(
|
||||
`v1-acceptance-run-complete passed=${manifest.summary.passed} failed=${manifest.summary.failed} evidence=${evidencePath}\n`,
|
||||
);
|
||||
if (failed.length > 0) {
|
||||
process.stderr.write(`failed acceptance: ${failed.map((result) => result.token).join(", ")}\n`);
|
||||
process.exitCode = 1;
|
||||
}
|
||||
Reference in New Issue
Block a user