Files
tech-log-frontend/scripts/lib/ci-contract-report.ts
T

46 lines
1.4 KiB
TypeScript

import { z } from "zod";
export const ciContractReportSchema = z
.object({
schemaVersion: z.literal(2),
nodeVersion: z.string().regex(/^\d+\.\d+\.\d+$/u),
gateCount: z.literal(26),
commandDefinitionCount: z.number().int().positive(),
commandReferenceCount: z.number().int().positive(),
artifactCount: z.number().int().positive(),
jobCount: z.literal(9),
workflowSha256: z.string().regex(/^[a-f0-9]{64}$/u),
durationStatus: z.string().min(1),
negativeFixtures: z.array(
z
.object({
readiness: z.enum([
"MERGE_READY",
"RELEASE_READY",
"PROD_PROMOTION_READY",
"FIELD_SLO_READY",
"DOCUMENTATION_READY",
]),
failedGate: z.string().regex(/^FE-GATE-\d{3}$/u),
passed: z.boolean(),
})
.strict(),
),
failures: z.array(z.string()),
passed: z.boolean(),
})
.strict()
.superRefine((report, context) => {
const fail = (path: PropertyKey[], message: string) =>
context.addIssue({ code: "custom", path, message });
if ((report.passed === true) !== (report.failures.length === 0)) {
fail(["passed"], "passed must agree with failures");
}
if (
report.negativeFixtures.length !== 5 ||
report.negativeFixtures.some((fixture) => !fixture.passed)
) {
fail(["negativeFixtures"], "every readiness negative fixture must pass");
}
});