58 lines
2.2 KiB
JavaScript
58 lines
2.2 KiB
JavaScript
/**
|
|
* CI quality gates for the GitHub Action.
|
|
*
|
|
* Pure decision helpers (severityBreached / isRegression) plus a CLI that reads
|
|
* the JSON report emitted by ci-review.mjs and exits non-zero when a gate is
|
|
* breached. Kept out of action.yml so the logic is unit-testable instead of
|
|
* living as an untested inline `node -e` block.
|
|
*
|
|
* Usage:
|
|
* node scripts/ci-gate.mjs --report brooks-lint-report.json \
|
|
* --fail-on critical --fail-on-regression true
|
|
*/
|
|
|
|
import { readFileSync } from "node:fs";
|
|
import { fileURLToPath } from "node:url";
|
|
import { parseArgs } from "./cli-utils.mjs";
|
|
|
|
/**
|
|
* True when findings at/above the `failOn` severity exist.
|
|
* @param {{critical?: number, warning?: number, suggestion?: number}} findings
|
|
* @param {"none"|"warning"|"critical"} failOn
|
|
*/
|
|
export function severityBreached(findings, failOn) {
|
|
const critical = findings?.critical ?? 0;
|
|
const warning = findings?.warning ?? 0;
|
|
if (failOn === "critical") return critical > 0;
|
|
if (failOn === "warning") return critical + warning > 0;
|
|
return false;
|
|
}
|
|
|
|
/** True when the Health Score regressed (delta is a negative number). */
|
|
export function isRegression(delta) {
|
|
return typeof delta === "number" && delta < 0;
|
|
}
|
|
|
|
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
const args = parseArgs(process.argv.slice(2));
|
|
const report = JSON.parse(readFileSync(args.report, "utf8"));
|
|
const failOn = args["fail-on"] ?? "none";
|
|
// parseArgs yields boolean true for a bare flag and a string otherwise.
|
|
const failOnRegression = String(args["fail-on-regression"]).toLowerCase() === "true";
|
|
|
|
let failed = false;
|
|
if (failOn !== "none" && severityBreached(report.findings, failOn)) {
|
|
console.error(`Severity gate failed (fail-on=${failOn}): ${JSON.stringify(report.findings)}`);
|
|
failed = true;
|
|
}
|
|
if (failOnRegression && report.delta == null) {
|
|
console.log("Regression gate inactive: no prior history (commit .brooks-lint-history.json to enable it).");
|
|
} else if (failOnRegression && isRegression(report.delta)) {
|
|
console.error(`Regression gate failed: ${report.previousScore} → ${report.score} (${report.delta})`);
|
|
failed = true;
|
|
}
|
|
|
|
if (failed) process.exit(1);
|
|
console.log("brooks-lint quality gates passed.");
|
|
}
|