88 lines
2.6 KiB
JavaScript
88 lines
2.6 KiB
JavaScript
import { createHash } from "node:crypto";
|
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
|
|
import { verifyCompatibilityTuple } from "../src/application/policies/compatibility.js";
|
|
import { compareReleaseToRuntime } from "../src/contracts/release-tokens.js";
|
|
|
|
const fixturesDocument =
|
|
/** @type {{
|
|
* fixtures: Array<{
|
|
* name: string,
|
|
* expectedCompatible: boolean,
|
|
* frontend: {
|
|
* buildId: string,
|
|
* configSchemaVersion: string,
|
|
* apiContractVersion: string,
|
|
* assetManifestHash: string,
|
|
* releaseId: string
|
|
* },
|
|
* runtime: {
|
|
* buildId: string,
|
|
* configSchemaVersion: string,
|
|
* apiContractVersion: string,
|
|
* assetManifestHash: string,
|
|
* releaseId: string
|
|
* }
|
|
* }>
|
|
* }} */ (
|
|
JSON.parse(
|
|
await readFile("config/release/coherence-fixtures.json", "utf8"),
|
|
)
|
|
);
|
|
const release = JSON.parse(await readFile("dist/release-manifest.json", "utf8"));
|
|
const runtimeConfig = JSON.parse(await readFile("dist/config.json", "utf8"));
|
|
const viteManifest = await readFile("dist/.vite/manifest.json");
|
|
const actualAssetManifestHash = createHash("sha256")
|
|
.update(viteManifest)
|
|
.digest("hex");
|
|
|
|
const artifactComparison = compareReleaseToRuntime(release, runtimeConfig);
|
|
const artifactMismatches = [...artifactComparison.mismatches];
|
|
if (release.assetManifestHash !== actualAssetManifestHash) {
|
|
artifactMismatches.push("assetManifestContent");
|
|
}
|
|
|
|
const fixtures = fixturesDocument.fixtures.map((fixture) => {
|
|
const result = verifyCompatibilityTuple({
|
|
frontend: fixture.frontend,
|
|
runtime: fixture.runtime,
|
|
});
|
|
return {
|
|
name: fixture.name,
|
|
expectedCompatible: fixture.expectedCompatible,
|
|
actualCompatible: result.compatible,
|
|
mismatches: result.mismatches,
|
|
passed: result.compatible === fixture.expectedCompatible,
|
|
};
|
|
});
|
|
const artifact = {
|
|
checked: true,
|
|
compatible: artifactComparison.compatible && artifactMismatches.length === 0,
|
|
mismatches: artifactMismatches,
|
|
releaseId: release.releaseId,
|
|
};
|
|
const passed = artifact.compatible && fixtures.every((fixture) => fixture.passed);
|
|
const report = {
|
|
schemaVersion: 1,
|
|
generatedAt: new Date().toISOString(),
|
|
artifact,
|
|
fixtures,
|
|
passed,
|
|
};
|
|
|
|
await mkdir("artifacts/release", { recursive: true });
|
|
await writeFile(
|
|
"artifacts/release/verification.json",
|
|
`${JSON.stringify(report, null, 2)}\n`,
|
|
);
|
|
|
|
if (!passed) {
|
|
process.stderr.write(
|
|
`Release coherence failed: ${artifactMismatches.join(", ") || "fixture"}\n`,
|
|
);
|
|
process.exit(1);
|
|
}
|
|
process.stdout.write(
|
|
`Release coherence: PASS (${fixtures.length - 1} mixed fixtures rejected)\n`,
|
|
);
|