Files
fusion/scripts/__tests__/workflow-reliability-release-check.test.mjs
gsxdsm 3383a095b7 FN-6694: add workflow reliability release-check harness
Add an on-demand executable release-check lane for custom workflow reliability signoff.

- Add a manifest-backed release-check runner with dry-run, JSON output, validation, and targeted Vitest command planning.
- Define the custom workflow reliability checklist seams and cover runner validation, planning, reporting, and failure behavior with node tests.
- Document the QA signoff command and manifest mapping while keeping the lane out of the merge gate.

Files changed:
 docs/custom-workflow-reliability-acceptance-map.md |  29 +-
 docs/testing.md                                    |   3 +
 package.json                                       |   1 +
 .../workflow-reliability-release-check.test.mjs    | 138 +++++++++
 .../lib/workflow-reliability-release-check.json    | 102 +++++++
 scripts/workflow-reliability-release-check.mjs     | 312 +++++++++++++++++++++
 6 files changed, 579 insertions(+), 6 deletions(-)

Fusion-Task-Id: FN-6694

Fusion-Task-Lineage: 21d45bb5-6c45-4cb7-8b29-9eaea8b29ad4
2026-06-19 05:13:39 -07:00

139 lines
5.6 KiB
JavaScript

import test from "node:test";
import assert from "node:assert/strict";
import path from "node:path";
import { existsSync } from "node:fs";
import { fileURLToPath } from "node:url";
import {
DEFAULT_MANIFEST_PATH,
loadManifest,
planCommands,
renderReport,
summarize,
validateManifest,
} from "../workflow-reliability-release-check.mjs";
const currentFilePath = fileURLToPath(import.meta.url);
const repoRoot = path.resolve(path.dirname(currentFilePath), "../..");
const expectedChecklistIds = [
"author-import-save-discover-reload",
"selected-workflow-execution-fail-closed",
"gate-advisory-readonly-revise-required-artifact",
"automerge-hard-cancel-file-scope-recovery",
"restart-selection-progress-run-audit",
];
function clone(value) {
return JSON.parse(JSON.stringify(value));
}
test("manifest parses, covers all five release-check items, and references existing seam files", () => {
const manifest = loadManifest(DEFAULT_MANIFEST_PATH, { rootDir: repoRoot });
assert.equal(manifest.version, 1);
assert.equal(typeof manifest._comment, "string");
assert.deepEqual(manifest.checklist.map((item) => item.id), expectedChecklistIds);
assert.equal(manifest.manual.length, 0);
for (const item of manifest.checklist) {
assert.equal(typeof item.title, "string");
assert.equal(typeof item.journey, "string");
assert.ok(item.seams.length >= 1, `${item.id} should map to at least one automated seam`);
for (const seam of item.seams) {
assert.match(seam.package, /^@fusion\/(core|dashboard|engine)$/);
assert.ok(existsSync(path.join(repoRoot, seam.file)), `${seam.file} should exist`);
}
}
assert.deepEqual(validateManifest(manifest, { repoRoot, existsSync }), { ok: true, errors: [] });
});
test("planned commands are targeted package-scoped vitest invocations", () => {
const manifest = loadManifest(DEFAULT_MANIFEST_PATH, { rootDir: repoRoot });
const commands = planCommands(manifest);
assert.deepEqual(commands.map((command) => command.package), ["@fusion/core", "@fusion/dashboard", "@fusion/engine"]);
for (const command of commands) {
assert.equal(command.command, "pnpm");
assert.deepEqual(command.args.slice(0, 5), ["--filter", command.package, "exec", "vitest", "run"]);
assert.ok(command.args.includes("--silent=passed-only"));
assert.ok(command.args.includes("--reporter=dot"));
assert.ok(command.files.length >= 1);
for (const file of command.files) assert.ok(file.startsWith("packages/"));
}
});
test("validateManifest fails closed on dangling seam files and uncovered checklist items", () => {
const manifest = loadManifest(DEFAULT_MANIFEST_PATH, { rootDir: repoRoot });
const dangling = clone(manifest);
dangling.checklist[0].seams[0].file = "packages/core/src/__tests__/missing-workflow-release-check.test.ts";
const danglingResult = validateManifest(dangling, { repoRoot, existsSync: (candidate) => !String(candidate).includes("missing-workflow-release-check") });
assert.equal(danglingResult.ok, false);
assert.match(danglingResult.errors.join("\n"), /file does not exist/);
const uncovered = clone(manifest);
uncovered.checklist[1].seams = [];
const uncoveredResult = validateManifest(uncovered, { repoRoot, existsSync: () => true });
assert.equal(uncoveredResult.ok, false);
assert.match(uncoveredResult.errors.join("\n"), /must have at least one seam or a manual automationDeferredReason/);
});
test("validateManifest rejects unknown packages and accepts explicit manual deferrals", () => {
const manifest = loadManifest(DEFAULT_MANIFEST_PATH, { rootDir: repoRoot });
const unknownPackage = clone(manifest);
unknownPackage.checklist[0].seams[0].package = "@fusion/unknown";
const unknownPackageResult = validateManifest(unknownPackage, { repoRoot, existsSync: () => true });
assert.equal(unknownPackageResult.ok, false);
assert.match(unknownPackageResult.errors.join("\n"), /unknown package/);
const manual = clone(manifest);
manual.checklist[0].seams = [];
manual.manual = [{
id: manual.checklist[0].id,
title: manual.checklist[0].title,
automationDeferredReason: "Requires a human-only external signoff artifact.",
}];
assert.deepEqual(validateManifest(manual, { repoRoot, existsSync: () => true }), { ok: true, errors: [] });
});
test("summarize and renderReport roll up pass, fail, manual, text, and stable JSON", () => {
const summary = summarize([
{
id: "passed-item",
title: "Passed item",
journey: "A passing synthetic item",
seams: [{ package: "@fusion/core", file: "one.test.ts", status: "PASS" }],
manual: null,
},
{
id: "failed-item",
title: "Failed item",
journey: "A failing synthetic item",
seams: [{ package: "@fusion/engine", file: "two.test.ts", status: "FAIL", exitCode: 1 }],
manual: null,
},
{
id: "manual-item",
title: "Manual item",
journey: "A manual synthetic item",
seams: [],
manual: { id: "manual-item", title: "Manual item", automationDeferredReason: "Human inspection only." },
},
]);
assert.equal(summary.ok, false);
assert.deepEqual(summary.counts, { pass: 1, fail: 1, manual: 1, total: 3 });
assert.deepEqual(summary.items.map((item) => item.status), ["PASS", "FAIL", "MANUAL"]);
const text = renderReport(summary);
assert.match(text, /Overall: FAIL \(1 passed, 1 failed, 1 manual, 3 total\)/);
assert.match(text, /FAIL: failed-item/);
assert.match(text, /MANUAL: Human inspection only\./);
const json = renderReport(summary, { json: true });
assert.deepEqual(JSON.parse(json), summary);
assert.ok(json.startsWith('{\n "ok": false,'));
});