Files
OmniRoute/scripts/quality/release-acceptance/nodeReporter.mjs
Bob.Hou e7214c72fc ci(acceptance): emit a shadow release-acceptance report next to release-green (#13701)
Adds a shadow release-acceptance report alongside release-green: an inventory/reduce/oracle pipeline under `scripts/quality/release-acceptance/` with a JSON schema, fixtures and a workflow that uploads the report as an artifact.

Contained by design, which is why it merges as-is: it runs only on push to `release/v*` and on manual dispatch (never on pull requests), the step is `continue-on-error`, `permissions: contents: read`, `persist-credentials: false`, and it consumes no secrets. Nothing in the product changes; the report is advisory until we decide to promote it.

Validated as a combined board first (this PR merged with the 11 siblings of the same batch on the release tip): eslint on every changed file with the suppressions file, typecheck:core, check:open-sse-typecheck, complexity, cognitive-complexity, changelog-integrity, i18n new-key coverage, docs-sync, migration-numbering, provider-consistency and a duplicate-identifier audit all green, plus 275 passing / 0 failing focused node:test cases across the 28 test files the batch touches. Then re-validated alone on the fresh tip before this merge: conflicts re-resolved, file sizes rebaselined for this PR's own growth, eslint and this PR's focused tests re-run.

Thanks @HouMinXi!
2026-09-16 03:17:52 -03:00

42 lines
1.1 KiB
JavaScript

const SUBTEST = /^# Subtest:\s+(\S+)/;
const RESULT = /^(ok|not ok)\s+\d+\s+-\s+(\S+)/;
export function fromNodeTestTap(tapText, argvFiles) {
const completed = [];
const failed = [];
const seen = new Set();
const lines = String(tapText ?? "").split(/\r?\n/);
let pending = null;
for (const line of lines) {
const sub = line.match(SUBTEST);
if (sub) {
pending = sub[1];
continue;
}
const res = line.match(RESULT);
if (res) {
const file = pending;
const ok = res[1] === "ok";
if (file) {
seen.add(file);
if (!ok) {
if (!failed.includes(file)) failed.push(file);
const i = completed.indexOf(file);
if (i >= 0) completed.splice(i, 1);
} else if (!failed.includes(file) && !completed.includes(file)) {
completed.push(file);
}
}
}
}
const attempted = [...argvFiles];
const missing = attempted.filter((f) => !seen.has(f));
return {
completed,
attempted,
missing,
failed,
pass: completed.length > 0 && missing.length === 0 && failed.length === 0,
};
}