feat(WP7-06): 增加最终AC预冻结门禁
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { createHash } from "node:crypto";
|
||||
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
import { validateTddTrace } from "./lib/tdd-trace.mjs";
|
||||
import { buildWp706PrefreezeReport, REQUIRED_UPSTREAM } from "./lib/wp7-06-prefreeze.mjs";
|
||||
|
||||
const runId = process.env.DADA_TDD_RUN_ID ?? `wp7-06-prefreeze-${new Date().toISOString().replace(/[^0-9]/g, "")}`;
|
||||
const runDirectory = resolve("artifacts", "tdd", runId);
|
||||
const caseDirectory = resolve(runDirectory, "cases", "TDD-WP7-AC-001-trace-structure");
|
||||
if (existsSync(runDirectory)) throw new Error(`Evidence run already exists: ${runId}`);
|
||||
mkdirSync(caseDirectory, { recursive: true });
|
||||
|
||||
function writeJson(path, value) {
|
||||
writeFileSync(path, `${JSON.stringify(value, null, 2)}\n`);
|
||||
}
|
||||
|
||||
function git(args) {
|
||||
const result = spawnSync("git", args, { encoding: "utf8", timeout: 60_000 });
|
||||
if ((result.status ?? 1) !== 0) throw new Error(`WP7_06_GIT_COMMAND_FAILED:${args[0]}`);
|
||||
return result.stdout.trim();
|
||||
}
|
||||
|
||||
function runCommand(name, command) {
|
||||
const startedAt = new Date().toISOString();
|
||||
const result = spawnSync(process.env.ComSpec ?? "cmd.exe", ["/d", "/s", "/c", command], {
|
||||
encoding: "utf8",
|
||||
env: process.env,
|
||||
maxBuffer: 64 * 1024 * 1024,
|
||||
});
|
||||
if (result.stdout) process.stdout.write(result.stdout);
|
||||
if (result.stderr) process.stderr.write(result.stderr);
|
||||
return {
|
||||
command,
|
||||
exit_code: result.status ?? 1,
|
||||
finished_at: new Date().toISOString(),
|
||||
name,
|
||||
started_at: startedAt,
|
||||
};
|
||||
}
|
||||
|
||||
const commands = [
|
||||
runCommand("prefreeze-unit", "node --test tests/package/wp7-06-prefreeze.test.mjs"),
|
||||
runCommand("tdd-trace", "pnpm validate:tdd-trace"),
|
||||
];
|
||||
if (commands.some((command) => command.exit_code !== 0)) {
|
||||
writeJson(resolve(caseDirectory, "commands.json"), { commands, run_id: runId, schema_version: "1.0" });
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const trace = validateTddTrace();
|
||||
const currentCommit = git(["rev-parse", "HEAD"]);
|
||||
const remoteLines = git(["ls-remote", "--heads", "origin", "codex/wp7-01", "codex/wp7-02", "codex/wp7-03", "codex/wp7-04", "codex/wp7-05"])
|
||||
.split(/\r?\n/)
|
||||
.filter(Boolean);
|
||||
const remoteHeads = Object.fromEntries(remoteLines.map((line) => {
|
||||
const [head, reference] = line.split(/\s+/);
|
||||
return [reference.replace("refs/heads/", ""), head];
|
||||
}));
|
||||
const upstream = Object.fromEntries(Object.entries(REQUIRED_UPSTREAM).map(([taskId, status]) => {
|
||||
const branch = taskId.replace("TASK-", "codex/").toLowerCase();
|
||||
const head = remoteHeads[branch];
|
||||
const ancestry = spawnSync("git", ["merge-base", "--is-ancestor", head ?? "missing", "HEAD"], { encoding: "utf8", timeout: 30_000 });
|
||||
return [taskId, { branch, head, merged: ancestry.status === 0, status }];
|
||||
}));
|
||||
const report = buildWp706PrefreezeReport({
|
||||
currentCommit,
|
||||
releaseExists: existsSync(resolve("RELEASE.json")),
|
||||
trace,
|
||||
upstream,
|
||||
});
|
||||
|
||||
const result = {
|
||||
acceptance_criteria: Array.from({ length: 56 }, (_, index) => index + 1)
|
||||
.filter((number) => ![8, 26, 37, 54].includes(number))
|
||||
.map((number) => `AC-${String(number).padStart(2, "0")}`),
|
||||
automation: ["automated", "manual_review"],
|
||||
commit: currentCommit,
|
||||
evidence_refs: ["commands.json", "trace-summary.json", "upstream-lineage.json", "deferred-external.json"],
|
||||
finished_at: new Date().toISOString(),
|
||||
manifest: {
|
||||
path: "tasks.manifest.json",
|
||||
sha256: createHash("sha256").update(readFileSync("tasks.manifest.json")).digest("hex").toUpperCase(),
|
||||
},
|
||||
missing_evidence: [],
|
||||
release_gate: ["release:P0-A"],
|
||||
requirements: ["NFR-05"],
|
||||
run_id: runId,
|
||||
schema_version: "1.0",
|
||||
status: report.status,
|
||||
task_id: "TASK-WP7-06",
|
||||
test_id: "TDD-WP7-AC-001-trace-structure",
|
||||
work_package: "WP-7",
|
||||
};
|
||||
|
||||
writeJson(resolve(caseDirectory, "commands.json"), { commands, run_id: runId, schema_version: "1.0" });
|
||||
writeJson(resolve(caseDirectory, "trace-summary.json"), { status: trace.status, summary: trace.summary, schema_version: "1.0" });
|
||||
writeJson(resolve(caseDirectory, "upstream-lineage.json"), { current_commit: currentCommit, tasks: report.upstream, schema_version: "1.0" });
|
||||
writeJson(resolve(caseDirectory, "deferred-external.json"), {
|
||||
policy: "product_owner_first_version_nonblocking",
|
||||
tasks: report.deferred_external_tasks,
|
||||
treated_as_real_provider_pass: false,
|
||||
schema_version: "1.0",
|
||||
});
|
||||
writeJson(resolve(caseDirectory, "result.json"), result);
|
||||
writeJson(resolve(runDirectory, "evidence.json"), { cases: [{ missing_evidence: [], status: result.status, test_id: result.test_id }], run_id: runId, status: result.status, schema_version: "1.0" });
|
||||
console.log(JSON.stringify({ deferred_external_tasks: report.deferred_external_tasks, next_task: report.next_task, run_id: runId, status: report.status }, null, 2));
|
||||
Reference in New Issue
Block a user