fix(pac): 收敛 HWLAB runtime GitOps 脚本体积

This commit is contained in:
Codex
2026-07-13 22:09:36 +02:00
parent d439f4cd29
commit 0e431e275e
6 changed files with 102 additions and 13 deletions
+2
View File
@@ -651,6 +651,7 @@ export interface HwlabRuntimePipelineProvenanceSpec {
readonly configRef: string;
readonly renderer: "hwlab-runtime-lane";
readonly mode: "remote-pipeline-annotation";
readonly maxInlineScriptBytes: number;
}
export interface HwlabRuntimeLaneSpec {
@@ -1083,6 +1084,7 @@ export function parseHwlabRuntimePipelineProvenance(
configRef,
renderer: enumStringField(raw, "renderer", path, ["hwlab-runtime-lane"]),
mode: enumStringField(raw, "mode", path, ["remote-pipeline-annotation"]),
maxInlineScriptBytes: boundedIntegerField(raw, "maxInlineScriptBytes", path, 1024, 131072),
};
}
@@ -238,6 +238,80 @@ describe("HWLAB YAML-owned Pipeline provenance", () => {
}, ownerPath, configRef)).toThrow("mode must be one of remote-pipeline-annotation");
});
test("runtime GitOps guard keeps Tekton scripts below the owning YAML budget", () => {
const temporary = mkdtempSync(resolve(tmpdir(), "unidesk-hwlab-runtime-gitops-guard-"));
try {
const spec = hwlabRuntimeLaneSpecForNode("v03", "NC01");
const budget = spec.pipelineProvenance?.maxInlineScriptBytes;
expect(budget).toBeNumber();
const overlay = nodeRuntimeRenderOverlay(spec);
const pipelinePath = resolve(temporary, "pipeline.yaml");
const configMapPath = resolve(temporary, "runtime-gitops-scripts.yaml");
const scriptsDir = rootPath("scripts", "native", "hwlab");
writeFileSync(pipelinePath, Bun.YAML.stringify({
apiVersion: "tekton.dev/v1",
kind: "Pipeline",
metadata: { name: spec.pipeline, namespace: "hwlab-ci" },
spec: { tasks: [{
name: "gitops-promote",
taskSpec: { steps: [{
name: "render",
script: "node scripts/run-bun.mjs scripts/gitops-render.mjs --use-deploy-images\nnode scripts/run-bun.mjs scripts/gitops-render.mjs --use-deploy-images --check\n",
}] },
}] },
}));
const result = spawnSync("node", [
rootPath("scripts", "native", "hwlab", "runtime-gitops-pipeline-guard.mjs"),
"--pipeline", pipelinePath,
"--scripts-configmap", configMapPath,
"--namespace", "hwlab-ci",
"--scripts-dir", scriptsDir,
], {
cwd: rootPath(),
env: { ...process.env, UNIDESK_RUNTIME_GITOPS_OVERLAY_B64: Buffer.from(JSON.stringify(overlay), "utf8").toString("base64") },
encoding: "utf8",
timeout: 30_000,
});
expect(result.status).toBe(0);
const pipeline = Bun.YAML.parse(readFileSync(pipelinePath, "utf8")) as Record<string, any>;
const scripts = pipeline.spec.tasks.flatMap((task: Record<string, any>) => task.taskSpec.steps.map((step: Record<string, any>) => String(step.script ?? "")));
expect(Math.max(...scripts.map((script: string) => Buffer.byteLength(script)))).toBeLessThanOrEqual(budget as number);
expect(scripts.join("\n")).toContain("UNIDESK_RUNTIME_GITOPS_OVERLAY_FILE=/etc/unidesk-cicd-runtime-gitops/runtime-gitops-overlay.json");
expect(scripts.join("\n")).not.toContain(Buffer.from(JSON.stringify(overlay.observability), "utf8").toString("base64"));
const configMap = Bun.YAML.parse(readFileSync(configMapPath, "utf8")) as Record<string, any>;
expect(JSON.parse(configMap.data["runtime-gitops-overlay.json"])).toEqual({ runtimePath: overlay.runtimePath, observability: overlay.observability });
expect(Object.keys(configMap.data).sort()).toEqual([
"runtime-gitops-observability.mjs",
"runtime-gitops-overlay.json",
"runtime-gitops-postprocess.mjs",
"runtime-gitops-verify.mjs",
]);
const legacyPayload = Buffer.from(JSON.stringify({ runtimePath: overlay.runtimePath, observability: overlay.observability }), "utf8").toString("base64");
const legacyPipeline = Bun.YAML.parse(readFileSync(pipelinePath, "utf8")) as Record<string, any>;
const legacyStep = legacyPipeline.spec.tasks[0].taskSpec.steps[0];
legacyStep.script = String(legacyStep.script).replaceAll(
"UNIDESK_RUNTIME_GITOPS_OVERLAY_FILE=/etc/unidesk-cicd-runtime-gitops/runtime-gitops-overlay.json",
`UNIDESK_RUNTIME_GITOPS_OVERLAY_B64='${legacyPayload}'`,
);
writeFileSync(pipelinePath, Bun.YAML.stringify(legacyPipeline));
const migrated = spawnSync("node", [
rootPath("scripts", "native", "hwlab", "runtime-gitops-pipeline-guard.mjs"),
"--pipeline", pipelinePath,
], {
cwd: rootPath(),
env: { ...process.env, UNIDESK_RUNTIME_GITOPS_OVERLAY_B64: Buffer.from(JSON.stringify(overlay), "utf8").toString("base64") },
encoding: "utf8",
timeout: 30_000,
});
expect(migrated.status).toBe(0);
const migratedText = readFileSync(pipelinePath, "utf8");
expect(migratedText).toContain("UNIDESK_RUNTIME_GITOPS_OVERLAY_FILE=/etc/unidesk-cicd-runtime-gitops/runtime-gitops-overlay.json");
expect(migratedText).not.toContain(legacyPayload);
} finally {
rmSync(temporary, { recursive: true, force: true });
}
});
test("normal control-plane postprocess writes exactly the shared four provenance fields", () => {
const temporary = mkdtempSync(resolve(tmpdir(), "unidesk-hwlab-pipeline-provenance-"));
try {
@@ -491,7 +565,16 @@ describe("runtime source-commit selection", () => {
configRef: "config/hwlab-node-lanes.yaml#lanes.v03.targets.NC01",
renderer: "hwlab-runtime-lane",
mode: "remote-pipeline-annotation",
maxInlineScriptBytes: 32768,
});
expect([
spec.codeAgentRuntime?.kafkaEventBridge.features.directPublish,
spec.codeAgentRuntime?.kafkaEventBridge.features.liveKafkaSse,
spec.codeAgentRuntime?.kafkaEventBridge.features.kafkaRefreshReplay,
spec.codeAgentRuntime?.kafkaEventBridge.features.transactionalProjector,
spec.codeAgentRuntime?.kafkaEventBridge.features.projectionOutboxRelay,
spec.codeAgentRuntime?.kafkaEventBridge.features.projectionRealtime,
]).toEqual([false, false, false, true, true, true]);
expect(remoteAnnotations).toEqual(pipelineProvenanceAnnotations(remoteProvenance));
expect(Object.keys(remoteAnnotations).sort()).toEqual(Object.values(pipelineProvenanceAnnotationKeys).sort());
expect(readFileSync(rootPath("scripts", "src", "hwlab-node", "render.ts"), "utf8")).not.toContain("overlay.sourceArtifactProvenance");