Files

59 lines
1.9 KiB
TypeScript

import { mkdir, readFile } from "node:fs/promises";
import { classifyObjectSchemaChange } from "../src/application/policies/compatibility.ts";
import { compatibilityFixturesArtifactSchema } from "./contracts/release-artifacts.ts";
import { writeValidatedJsonArtifact } from "./lib/validated-json-artifact.ts";
type CompatibilitySchema = Readonly<{
required?: readonly string[];
properties?: Readonly<Record<string, unknown>>;
}>;
type CompatibilityFixture = Readonly<{
before: CompatibilitySchema;
after: CompatibilitySchema;
}>;
type CompatibilityFixtures = Readonly<{
families: Readonly<
Record<string, Readonly<Record<"additive" | "breaking", CompatibilityFixture>>>
>;
}>;
const fixtures = JSON.parse(
await readFile("config/compatibility/fixtures.json", "utf8"),
) as CompatibilityFixtures;
const results = [];
for (const [family, cases] of Object.entries(fixtures.families)) {
for (const expected of ["additive", "breaking"] as const) {
const fixture = cases[expected];
const actual = classifyObjectSchemaChange(fixture.before, fixture.after);
results.push({ family, expected, actual, passed: actual === expected });
}
}
await mkdir("artifacts/release", { recursive: true });
await writeValidatedJsonArtifact({
path: "artifacts/release/compatibility.json",
schema: compatibilityFixturesArtifactSchema,
value: {
schemaVersion: 1,
generatedAt: new Date().toISOString(),
rules: [
"additive changes preserve required fields",
"breaking changes require version bump and migration, discard, fallback, or rollback",
"config and API major versions must match",
"incompatible persisted cache is discarded by default",
"rollback uses a coherent compatibility tuple",
],
results,
},
});
if (results.some((result) => !result.passed)) {
process.stderr.write("Compatibility fixture classification failed.\n");
process.exit(1);
}
process.stdout.write("Compatibility fixtures: PASS\n");