refactor: 리펙토링
This commit is contained in:
+52
-63
@@ -7,12 +7,23 @@ import {
|
||||
} from "../src/application/policies/compatibility.ts";
|
||||
import {
|
||||
compareReleaseToRuntime,
|
||||
RELEASE_TOKEN_REGISTRY,
|
||||
} from "../src/contracts/release-tokens.ts";
|
||||
import {
|
||||
parseBuildManifestArtifact,
|
||||
parseReleaseArtifact,
|
||||
parseRuntimeConfigArtifact,
|
||||
projectReleaseTokens,
|
||||
type BuildManifestArtifact,
|
||||
type ReleaseArtifact,
|
||||
type RuntimeConfigArtifact,
|
||||
} from "../src/contracts/release-artifacts.ts";
|
||||
import { verifyContractSet } from "../src/contracts/contract-set.ts";
|
||||
import { EXPECTED_CONTRACT_SET_PACKAGES } from "../src/features/installed-contract-contributions.ts";
|
||||
import {
|
||||
ROUTE_REGISTRY,
|
||||
ROUTE_RUNTIME_CONTRACT,
|
||||
} from "../src/features/installed-feature-contracts.ts";
|
||||
import { assertMatchesJsonSchema } from "./lib/json-schema.ts";
|
||||
|
||||
type CoherenceFixture = Readonly<{
|
||||
name: string;
|
||||
@@ -20,23 +31,8 @@ type CoherenceFixture = Readonly<{
|
||||
frontend: CompatibilityTuple;
|
||||
runtime: CompatibilityTuple;
|
||||
}>;
|
||||
type ReleaseDocument = CompatibilityTuple &
|
||||
Record<string, unknown> &
|
||||
Readonly<{ releaseId: string; routeChunks: Readonly<Record<string, unknown>> }>;
|
||||
type RuntimeConfigDocument = Readonly<{
|
||||
BUILD_ID: string;
|
||||
CONFIG_SCHEMA_VERSION: string;
|
||||
API_CONTRACT_VERSION: string;
|
||||
RELEASE_ID: string;
|
||||
}>;
|
||||
type BuildManifestDocument = Readonly<
|
||||
Record<string, unknown> & {
|
||||
outputs?: Readonly<{
|
||||
runtimeConfigSchema?: unknown;
|
||||
routeChunks?: Readonly<Record<string, unknown>>;
|
||||
}>;
|
||||
}
|
||||
>;
|
||||
type RuntimeConfigDocument = RuntimeConfigArtifact &
|
||||
Readonly<{ BUILD_ID: string; RELEASE_ID: string }>;
|
||||
type ViteManifestEntry = Readonly<{
|
||||
file: string;
|
||||
name?: string;
|
||||
@@ -54,9 +50,17 @@ const release = parseReleaseDocument(
|
||||
const runtimeConfig = parseRuntimeConfigDocument(
|
||||
JSON.parse(await readFile("dist/config.json", "utf8")),
|
||||
);
|
||||
const buildManifest = parseBuildManifestDocument(
|
||||
JSON.parse(await readFile("artifacts/release/build-manifest.json", "utf8")),
|
||||
const buildManifestDocument: unknown = JSON.parse(
|
||||
await readFile("artifacts/release/build-manifest.json", "utf8"),
|
||||
);
|
||||
assertMatchesJsonSchema(
|
||||
JSON.parse(
|
||||
await readFile("schemas/artifacts/build-manifest.schema.json", "utf8"),
|
||||
),
|
||||
buildManifestDocument,
|
||||
"build manifest",
|
||||
);
|
||||
const buildManifest = parseBuildManifestDocument(buildManifestDocument);
|
||||
const runtimeConfigJsonSchema = requireRecord(
|
||||
JSON.parse(await readFile("dist/runtime-config.schema.json", "utf8")),
|
||||
"runtime config JSON schema",
|
||||
@@ -69,11 +73,20 @@ const actualAssetManifestHash = createHash("sha256")
|
||||
|
||||
const artifactComparison = compareReleaseToRuntime(release, runtimeConfig);
|
||||
const artifactMismatches: string[] = [...artifactComparison.mismatches];
|
||||
for (const token of Object.keys(RELEASE_TOKEN_REGISTRY)) {
|
||||
if (typeof release[token] !== "string" || release[token].length === 0) {
|
||||
for (const [token, value] of Object.entries(projectReleaseTokens(release))) {
|
||||
if (token !== "schemaVersion" && (typeof value !== "string" || value.length === 0)) {
|
||||
artifactMismatches.push(`releaseToken:${token}`);
|
||||
}
|
||||
}
|
||||
if (release.schemaVersion === 2) {
|
||||
const contractSetVerification = await verifyContractSet({
|
||||
expected: EXPECTED_CONTRACT_SET_PACKAGES,
|
||||
manifest: release.contractSet,
|
||||
});
|
||||
if (!contractSetVerification.ok) {
|
||||
artifactMismatches.push(contractSetVerification.code);
|
||||
}
|
||||
}
|
||||
if (
|
||||
typeof release.builtAt !== "string" ||
|
||||
!Number.isFinite(Date.parse(release.builtAt))
|
||||
@@ -91,19 +104,19 @@ if (
|
||||
artifactMismatches.push("runtimeConfigSchema");
|
||||
}
|
||||
if (
|
||||
buildManifest.outputs?.runtimeConfigSchema !==
|
||||
buildManifest.outputs.runtimeConfigSchema !==
|
||||
"dist/runtime-config.schema.json"
|
||||
) {
|
||||
artifactMismatches.push("buildManifest:runtimeConfigSchema");
|
||||
}
|
||||
for (const [buildToken, releaseToken] of [
|
||||
["buildId", "buildId"],
|
||||
["commitSha", "commitSha"],
|
||||
["releaseId", "releaseId"],
|
||||
["generatedAt", "builtAt"],
|
||||
]) {
|
||||
if (buildManifest[buildToken] !== release[releaseToken]) {
|
||||
artifactMismatches.push(`buildManifest:${buildToken}`);
|
||||
for (const [token, buildValue, releaseValue] of [
|
||||
["buildId", buildManifest.buildId, release.buildId],
|
||||
["commitSha", buildManifest.commitSha, release.commitSha],
|
||||
["releaseId", buildManifest.releaseId, release.releaseId],
|
||||
["generatedAt", buildManifest.generatedAt, release.builtAt],
|
||||
] as const) {
|
||||
if (buildValue !== releaseValue) {
|
||||
artifactMismatches.push(`buildManifest:${token}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +147,7 @@ for (const definition of Object.values(ROUTE_REGISTRY)) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
buildManifest.outputs?.routeChunks?.[definition.chunkId] !== routeAsset
|
||||
buildManifest.outputs.routeChunks[definition.chunkId] !== routeAsset
|
||||
) {
|
||||
artifactMismatches.push(`buildManifest:routeChunk:${definition.chunkId}`);
|
||||
}
|
||||
@@ -221,45 +234,21 @@ function parseFixturesDocument(value: unknown): Readonly<{
|
||||
};
|
||||
}
|
||||
|
||||
function parseReleaseDocument(value: unknown): ReleaseDocument {
|
||||
const document = requireRecord(value, "release manifest");
|
||||
const tuple = parseCompatibilityTuple(document, "release manifest");
|
||||
const routeChunks = isRecord(document.routeChunks)
|
||||
? document.routeChunks
|
||||
: {};
|
||||
return { ...document, ...tuple, routeChunks };
|
||||
function parseReleaseDocument(value: unknown): ReleaseArtifact {
|
||||
return parseReleaseArtifact(value);
|
||||
}
|
||||
|
||||
function parseRuntimeConfigDocument(value: unknown): RuntimeConfigDocument {
|
||||
const document = requireRecord(value, "runtime config");
|
||||
const document = parseRuntimeConfigArtifact(value);
|
||||
return {
|
||||
...document,
|
||||
BUILD_ID: requireString(document.BUILD_ID, "runtime config BUILD_ID"),
|
||||
CONFIG_SCHEMA_VERSION: requireString(
|
||||
document.CONFIG_SCHEMA_VERSION,
|
||||
"runtime config CONFIG_SCHEMA_VERSION",
|
||||
),
|
||||
API_CONTRACT_VERSION: requireString(
|
||||
document.API_CONTRACT_VERSION,
|
||||
"runtime config API_CONTRACT_VERSION",
|
||||
),
|
||||
RELEASE_ID: requireString(
|
||||
document.RELEASE_ID,
|
||||
"runtime config RELEASE_ID",
|
||||
),
|
||||
RELEASE_ID: requireString(document.RELEASE_ID, "runtime config RELEASE_ID"),
|
||||
};
|
||||
}
|
||||
|
||||
function parseBuildManifestDocument(value: unknown): BuildManifestDocument {
|
||||
const document = requireRecord(value, "build manifest");
|
||||
const outputs = isRecord(document.outputs)
|
||||
? {
|
||||
runtimeConfigSchema: document.outputs.runtimeConfigSchema,
|
||||
routeChunks: isRecord(document.outputs.routeChunks)
|
||||
? document.outputs.routeChunks
|
||||
: undefined,
|
||||
}
|
||||
: undefined;
|
||||
return { ...document, ...(outputs ? { outputs } : {}) };
|
||||
function parseBuildManifestDocument(value: unknown): BuildManifestArtifact {
|
||||
return parseBuildManifestArtifact(value);
|
||||
}
|
||||
|
||||
function parseCompatibilityTuple(value: unknown, label: string): CompatibilityTuple {
|
||||
|
||||
Reference in New Issue
Block a user