95 lines
3.1 KiB
JavaScript
95 lines
3.1 KiB
JavaScript
import { createHash } from "node:crypto";
|
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
import process from "node:process";
|
|
import { z } from "zod";
|
|
|
|
import { ROUTE_REGISTRY } from "../src/contracts/routes.js";
|
|
import { ROUTE_RUNTIME_CONTRACT } from "../src/contracts/route-runtime-contract.js";
|
|
import { runtimeConfigSchema } from "../src/bootstrap/runtime-config-schema.js";
|
|
|
|
const packageJson = JSON.parse(await readFile("package.json", "utf8"));
|
|
const packageManagerVersion = packageJson.packageManager.split("@").at(-1);
|
|
const buildId = process.env.VITE_BUILD_ID ?? "local-build";
|
|
const commitSha = process.env.VITE_COMMIT_SHA ?? "local";
|
|
const releaseId = process.env.RELEASE_ID ?? "local-release";
|
|
const runnerImage = process.env.CI_RUNNER_IMAGE ?? `${process.platform}-${process.arch}`;
|
|
const builtAt = new Date().toISOString();
|
|
const viteManifest = await readFile("dist/.vite/manifest.json", "utf8");
|
|
const viteManifestObject =
|
|
/** @type {Record<string, {file: string, name?: string, isDynamicEntry?: boolean}>} */ (
|
|
JSON.parse(viteManifest)
|
|
);
|
|
const assetManifestHash = createHash("sha256")
|
|
.update(viteManifest)
|
|
.digest("hex");
|
|
const runtimeConfig = JSON.parse(await readFile("dist/config.json", "utf8"));
|
|
/** @type {Record<string, string>} */
|
|
const routeChunks = {};
|
|
for (const definition of Object.values(ROUTE_REGISTRY)) {
|
|
const runtime =
|
|
/** @type {Record<string, {moduleId: string}>} */ (
|
|
ROUTE_RUNTIME_CONTRACT
|
|
)[definition.routeId];
|
|
const asset = Object.values(viteManifestObject).find(
|
|
(entry) => entry.name === runtime?.moduleId && entry.isDynamicEntry,
|
|
);
|
|
if (!runtime || !asset?.file) {
|
|
throw new Error(`Missing built route chunk: ${definition.routeId}`);
|
|
}
|
|
routeChunks[definition.chunkId] = asset.file;
|
|
}
|
|
const runtimeConfigJsonSchema = z.toJSONSchema(runtimeConfigSchema);
|
|
|
|
runtimeConfig.BUILD_ID = buildId;
|
|
runtimeConfig.RELEASE_ID = releaseId;
|
|
|
|
const manifest = {
|
|
schemaVersion: 1,
|
|
buildId,
|
|
commitSha,
|
|
generatedAt: builtAt,
|
|
buildContext: {
|
|
nodeVersion: process.version,
|
|
packageManagerVersion,
|
|
runnerImage,
|
|
},
|
|
outputs: {
|
|
directory: "dist",
|
|
viteManifest: "dist/.vite/manifest.json",
|
|
routeChunks,
|
|
runtimeConfigSchema: "dist/runtime-config.schema.json",
|
|
},
|
|
};
|
|
|
|
const releaseManifest = {
|
|
schemaVersion: 1,
|
|
appVersion: packageJson.version,
|
|
buildId,
|
|
commitSha,
|
|
configSchemaVersion: runtimeConfig.CONFIG_SCHEMA_VERSION,
|
|
apiContractVersion: runtimeConfig.API_CONTRACT_VERSION,
|
|
assetManifestHash,
|
|
releaseId,
|
|
builtAt,
|
|
routeChunks,
|
|
};
|
|
|
|
await mkdir("artifacts/release", { recursive: true });
|
|
await writeFile("dist/config.json", `${JSON.stringify(runtimeConfig, null, 2)}\n`);
|
|
await writeFile(
|
|
"dist/release-manifest.json",
|
|
`${JSON.stringify(releaseManifest, null, 2)}\n`,
|
|
);
|
|
await writeFile(
|
|
"dist/runtime-config.schema.json",
|
|
`${JSON.stringify(runtimeConfigJsonSchema, null, 2)}\n`,
|
|
);
|
|
await writeFile(
|
|
"artifacts/release/runtime-config.schema.json",
|
|
`${JSON.stringify(runtimeConfigJsonSchema, null, 2)}\n`,
|
|
);
|
|
await writeFile(
|
|
"artifacts/release/build-manifest.json",
|
|
`${JSON.stringify(manifest, null, 2)}\n`,
|
|
);
|