fix: patch runtime GitOps YAML workloads
This commit is contained in:
@@ -2,8 +2,12 @@
|
||||
// SPEC: PJ2026-01060703 CI/CD branch follower runtime GitOps postprocess.
|
||||
// Responsibility: mutate rendered runtime GitOps files after HWLAB source render, before publish.
|
||||
import { existsSync, readdirSync, readFileSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
||||
import { createRequire } from "node:module";
|
||||
import path from "node:path";
|
||||
|
||||
const requireFromScript = createRequire(import.meta.url);
|
||||
const requireFromCwd = createRequire(path.join(process.cwd(), "package.json"));
|
||||
const YAML = requireYaml();
|
||||
const repoDir = process.cwd();
|
||||
const overlay = readOverlay();
|
||||
const runtimePath = requiredOverlayString("runtimePath");
|
||||
@@ -45,28 +49,29 @@ function patchCodeAgentRuntimeWorkloads() {
|
||||
const kafka = runtime.kafkaEventBridge;
|
||||
let changed = false;
|
||||
for (const file of listYamlFiles(runtimeDir)) {
|
||||
const parsed = parseJsonDocument(readFileSync(file, "utf8"));
|
||||
if (parsed === null) continue;
|
||||
const items = isKubernetesList(parsed) ? parsed.items : [parsed];
|
||||
const documents = parseStructuredDocuments(readFileSync(file, "utf8"), file);
|
||||
let fileChanged = false;
|
||||
for (const item of items) {
|
||||
const workloadName = String(item?.metadata?.labels?.["app.kubernetes.io/name"] ?? item?.metadata?.name ?? "");
|
||||
const containers = item?.spec?.template?.spec?.containers;
|
||||
if (!Array.isArray(containers)) continue;
|
||||
for (const container of containers) {
|
||||
if (!Array.isArray(container?.env)) continue;
|
||||
if (workloadName === "hwlab-cloud-api" && container.name === "hwlab-cloud-api") {
|
||||
fileChanged = patchCloudApiKafkaEnv(container, kafka) || fileChanged;
|
||||
}
|
||||
if (workloadName === "hwlab-cloud-web" && container.name === "hwlab-cloud-web") {
|
||||
fileChanged = setEnvValue(container, "HWLAB_WORKBENCH_LIVE_KAFKA_SSE_ENABLED", String(kafka.enabled && kafka.features.liveKafkaSse)) || fileChanged;
|
||||
fileChanged = setEnvValue(container, "HWLAB_WORKBENCH_KAFKA_REFRESH_REPLAY_ENABLED", String(kafka.enabled && kafka.features.kafkaRefreshReplay)) || fileChanged;
|
||||
fileChanged = setEnvValue(container, "HWLAB_WORKBENCH_PROJECTION_REALTIME_ENABLED", String(kafka.enabled && kafka.features.projectionRealtime)) || fileChanged;
|
||||
for (const document of documents.values) {
|
||||
const items = isKubernetesList(document) ? document.items : [document];
|
||||
for (const item of items) {
|
||||
const workloadName = String(item?.metadata?.labels?.["app.kubernetes.io/name"] ?? item?.metadata?.name ?? "");
|
||||
const containers = item?.spec?.template?.spec?.containers;
|
||||
if (!Array.isArray(containers)) continue;
|
||||
for (const container of containers) {
|
||||
if (!Array.isArray(container?.env)) continue;
|
||||
if (workloadName === "hwlab-cloud-api" && container.name === "hwlab-cloud-api") {
|
||||
fileChanged = patchCloudApiKafkaEnv(container, kafka) || fileChanged;
|
||||
}
|
||||
if (workloadName === "hwlab-cloud-web" && container.name === "hwlab-cloud-web") {
|
||||
fileChanged = setEnvValue(container, "HWLAB_WORKBENCH_LIVE_KAFKA_SSE_ENABLED", String(kafka.enabled && kafka.features.liveKafkaSse)) || fileChanged;
|
||||
fileChanged = setEnvValue(container, "HWLAB_WORKBENCH_KAFKA_REFRESH_REPLAY_ENABLED", String(kafka.enabled && kafka.features.kafkaRefreshReplay)) || fileChanged;
|
||||
fileChanged = setEnvValue(container, "HWLAB_WORKBENCH_PROJECTION_REALTIME_ENABLED", String(kafka.enabled && kafka.features.projectionRealtime)) || fileChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fileChanged) {
|
||||
writeFileSync(file, `${JSON.stringify(parsed, null, 2)}\n`, "utf8");
|
||||
writeFileSync(file, serializeStructuredDocuments(documents), "utf8");
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
@@ -237,6 +242,20 @@ function parseJsonDocument(text) {
|
||||
}
|
||||
}
|
||||
|
||||
function parseStructuredDocuments(text, file) {
|
||||
const json = parseJsonDocument(text);
|
||||
if (json !== null) return { format: "json", values: [json] };
|
||||
const documents = YAML.parseAllDocuments(text);
|
||||
const errors = documents.flatMap((document) => document.errors);
|
||||
if (errors.length > 0) throw new Error(`invalid YAML in ${file}: ${errors.map((error) => error.message).join("; ")}`);
|
||||
return { format: "yaml", values: documents.map((document) => document.toJS()).filter((document) => document !== null) };
|
||||
}
|
||||
|
||||
function serializeStructuredDocuments(documents) {
|
||||
if (documents.format === "json") return `${JSON.stringify(documents.values[0], null, 2)}\n`;
|
||||
return `${documents.values.map((document) => YAML.stringify(document).trimEnd()).join("\n---\n")}\n`;
|
||||
}
|
||||
|
||||
function leadingSpaces(value) {
|
||||
const match = value.match(/^ */u);
|
||||
return match ? match[0].length : 0;
|
||||
@@ -264,6 +283,14 @@ function readOverlay() {
|
||||
return JSON.parse(Buffer.from(encoded, "base64").toString("utf8"));
|
||||
}
|
||||
|
||||
function requireYaml() {
|
||||
try {
|
||||
return requireFromScript("yaml");
|
||||
} catch {
|
||||
return requireFromCwd("yaml");
|
||||
}
|
||||
}
|
||||
|
||||
function requiredOverlayString(name) {
|
||||
const value = overlay[name];
|
||||
if (typeof value !== "string" || value.length === 0) throw new Error(`overlay.${name} is required`);
|
||||
|
||||
Reference in New Issue
Block a user