refactor: 프론트 템플릿 리펙토링
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { mkdir, readFile } from "node:fs/promises";
|
||||
|
||||
import { classifyObjectSchemaChange } from "../src/application/policies/compatibility.ts";
|
||||
import { classifyObjectSchemaChange } from "../src/contracts/compatibility.ts";
|
||||
import { compatibilityFixturesArtifactSchema } from "./contracts/release-artifacts.ts";
|
||||
import { writeValidatedJsonArtifact } from "./lib/validated-json-artifact.ts";
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
import { constants } from "node:fs";
|
||||
import { access, readFile } from "node:fs/promises";
|
||||
import { spawnSync } from "node:child_process";
|
||||
|
||||
const failures: string[] = [];
|
||||
|
||||
async function requireExecutable(path: string, label: string): Promise<void> {
|
||||
try {
|
||||
await access(path, constants.X_OK);
|
||||
} catch {
|
||||
failures.push(`${label} is required at ${path}`);
|
||||
}
|
||||
}
|
||||
|
||||
await Promise.all([
|
||||
requireExecutable("/usr/bin/bwrap", "bubblewrap"),
|
||||
requireExecutable("/usr/bin/systemctl", "systemctl"),
|
||||
requireExecutable("/usr/bin/tar", "tar"),
|
||||
]);
|
||||
|
||||
try {
|
||||
const controllers = await readFile("/sys/fs/cgroup/cgroup.controllers", "utf8");
|
||||
if (controllers.trim().length === 0) {
|
||||
failures.push("cgroup v2 controllers are unavailable");
|
||||
}
|
||||
} catch {
|
||||
failures.push("cgroup v2 is required at /sys/fs/cgroup/cgroup.controllers");
|
||||
}
|
||||
|
||||
if (!failures.some((failure) => failure.includes("systemctl"))) {
|
||||
const probe = spawnSync("/usr/bin/systemctl", ["show-environment"], {
|
||||
encoding: "utf8",
|
||||
timeout: 3_000,
|
||||
});
|
||||
if (probe.error || probe.status !== 0) {
|
||||
failures.push("a reachable systemd manager bus is required");
|
||||
}
|
||||
}
|
||||
|
||||
if (failures.length > 0) {
|
||||
process.stderr.write(
|
||||
[
|
||||
"System/CI-runner test prerequisites are unavailable:",
|
||||
...failures.map((failure) => ` - ${failure}`),
|
||||
"",
|
||||
"Run test:unit/test:contract/test:component/test:integration for the",
|
||||
"developer loop. test:system is intentionally reserved for a compatible",
|
||||
"Linux CI-runner host.",
|
||||
"",
|
||||
].join("\n"),
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
process.stdout.write("System test prerequisites: PASS\n");
|
||||
@@ -443,7 +443,7 @@ export type LoadCiGateContractOptions = Readonly<{
|
||||
}>;
|
||||
|
||||
const CANONICAL_GATE_SHAPE_SHA256 =
|
||||
"4617ada21cbdeb217d118146bd572860d7c58ad222142a52d41916b26577239a";
|
||||
"372959f50b9c5a228bdc85dce33ca7968c72414ce3b6d5534c9e6eaf554f6ce4";
|
||||
|
||||
function canonicalGateShapeSha256(gates: CiGateContract["gates"]): string {
|
||||
const normalized = gates.map(
|
||||
@@ -477,13 +477,13 @@ function canonicalAuthorityBaselineFailures(contract: CiGateContract): string[]
|
||||
if (contract.gates.length !== 27) {
|
||||
failures.push(`gate authority baseline must contain exactly 27 gates; received ${contract.gates.length}`);
|
||||
}
|
||||
if (contract.commands.length !== 82 || commandReferenceCount !== 94) {
|
||||
if (contract.commands.length !== 84 || commandReferenceCount !== 96) {
|
||||
failures.push(
|
||||
`command authority baseline must contain exactly 82 definitions and 94 references; received ${contract.commands.length} definitions and ${commandReferenceCount} references`,
|
||||
`command authority baseline must contain exactly 84 definitions and 96 references; received ${contract.commands.length} definitions and ${commandReferenceCount} references`,
|
||||
);
|
||||
}
|
||||
if (contract.artifacts.length !== 107) {
|
||||
failures.push(`artifact authority baseline must contain exactly 107 artifacts; received ${contract.artifacts.length}`);
|
||||
if (contract.artifacts.length !== 109) {
|
||||
failures.push(`artifact authority baseline must contain exactly 109 artifacts; received ${contract.artifacts.length}`);
|
||||
}
|
||||
if (contract.stages.length !== 5) {
|
||||
failures.push(`stage authority baseline must contain exactly 5 stages; received ${contract.stages.length}`);
|
||||
|
||||
@@ -3,7 +3,7 @@ import { pathToFileURL } from "node:url";
|
||||
|
||||
import { shouldRetry } from "../src/adapters/http/retry-policy.ts";
|
||||
import { createTelemetryAdapter } from "../src/adapters/telemetry/best-effort-telemetry.ts";
|
||||
import { verifyCompatibilityTuple } from "../src/application/policies/compatibility.ts";
|
||||
import { verifyCompatibilityTuple } from "../src/contracts/compatibility.ts";
|
||||
import type { StoragePort } from "../src/application/ports/storage-port.ts";
|
||||
import { decideChunkRecovery } from "../src/application/use-cases/decide-chunk-recovery.ts";
|
||||
import { validateRuntimeConfig } from "../src/bootstrap/runtime-config-schema.ts";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { isVersionCompatible } from "../../src/application/policies/compatibility.ts";
|
||||
import { isVersionCompatible } from "../../src/contracts/compatibility.ts";
|
||||
import { verifyContractSet } from "../../src/contracts/contract-set.ts";
|
||||
import type { InstalledContractPackageIdentity } from "../../src/contracts/external-contract-runtime.ts";
|
||||
import type { ReleaseArtifact } from "../../src/contracts/release-artifacts.ts";
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { existsSync } from "node:fs";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
function assertSupportedNode(): void {
|
||||
const [majorText = "0", minorText = "0"] = process.versions.node.split(".");
|
||||
const major = Number(majorText);
|
||||
const minor = Number(minorText);
|
||||
|
||||
if (major !== 24 || minor < 11) {
|
||||
process.stderr.write(
|
||||
[
|
||||
`Unsupported Node.js runtime for tests: ${process.versions.node}`,
|
||||
"Required by package.json: >=24.11.0 <25.0.0",
|
||||
"Use the repository-supported Node.js runtime before running a test suite.",
|
||||
"",
|
||||
].join("\n"),
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
assertSupportedNode();
|
||||
|
||||
const vitestEntry = fileURLToPath(
|
||||
new URL("../node_modules/vitest/vitest.mjs", import.meta.url),
|
||||
);
|
||||
if (!existsSync(vitestEntry)) {
|
||||
process.stderr.write(
|
||||
"Vitest is not installed. Run the repository package installation first.\n",
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const testEnvironment: NodeJS.ProcessEnv = {
|
||||
...process.env,
|
||||
NODE_ENV: "test",
|
||||
};
|
||||
for (const key of [
|
||||
"npm_config_userconfig",
|
||||
"npm_config_prefix",
|
||||
"npm_config_globalconfig",
|
||||
"NPM_CONFIG_USERCONFIG",
|
||||
"NPM_CONFIG_PREFIX",
|
||||
"NPM_CONFIG_GLOBALCONFIG",
|
||||
]) {
|
||||
delete testEnvironment[key];
|
||||
}
|
||||
|
||||
const result = spawnSync(
|
||||
process.execPath,
|
||||
[vitestEntry, ...process.argv.slice(2)],
|
||||
{
|
||||
stdio: "inherit",
|
||||
env: testEnvironment,
|
||||
},
|
||||
);
|
||||
|
||||
if (result.error) {
|
||||
throw result.error;
|
||||
}
|
||||
if (result.signal) {
|
||||
process.stderr.write(`Vitest terminated by signal ${result.signal}.\n`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
process.exit(result.status ?? 1);
|
||||
@@ -5,7 +5,7 @@ import { pathToFileURL } from "node:url";
|
||||
import {
|
||||
verifyCompatibilityTuple,
|
||||
type CompatibilityTuple,
|
||||
} from "../src/application/policies/compatibility.ts";
|
||||
} from "../src/contracts/compatibility.ts";
|
||||
import type { InstalledContractPackageIdentity } from "../src/contracts/external-contract-runtime.ts";
|
||||
import {
|
||||
parseBuildManifestArtifact,
|
||||
|
||||
Reference in New Issue
Block a user