From bb3607867575dcdb595d9899763a27ee834e0d72 Mon Sep 17 00:00:00 2001 From: Codex Agent Date: Sat, 6 Jun 2026 00:25:34 +0800 Subject: [PATCH] fix: publish v02 code agent bundle commit --- scripts/g14-gitops-render.mjs | 6 ++- scripts/g14-gitops-render.test.ts | 86 +++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/scripts/g14-gitops-render.mjs b/scripts/g14-gitops-render.mjs index be441bbf..f31171c9 100644 --- a/scripts/g14-gitops-render.mjs +++ b/scripts/g14-gitops-render.mjs @@ -1892,6 +1892,9 @@ function scrub(value) { if (Array.isArray(value)) return value.map(scrub); if (!value || typeof value !== "object") return value; const result = {}; + const semanticRuntimeCommitEnvNames = new Set([ + "HWLAB_CODE_AGENT_AGENTRUN_SOURCE_COMMIT" + ]); for (const [key, child] of Object.entries(value)) { if (key === "hwlab.pikastech.local/source-commit" || key === "hwlab.pikastech.local/artifact-source-commit" || @@ -1901,7 +1904,8 @@ function scrub(value) { result[key] = ""; continue; } - if (key === "value" && /^HWLAB_.*COMMIT/.test(String(value.name || ""))) { + const envName = String(value.name || ""); + if (key === "value" && /^HWLAB_.*COMMIT/.test(envName) && !semanticRuntimeCommitEnvNames.has(envName)) { result[key] = ""; continue; } diff --git a/scripts/g14-gitops-render.test.ts b/scripts/g14-gitops-render.test.ts index 210741da..ee36e413 100644 --- a/scripts/g14-gitops-render.test.ts +++ b/scripts/g14-gitops-render.test.ts @@ -11,6 +11,70 @@ function taskByName(pipeline, name) { return task; } +function extractRuntimeNoopDecisionScript(gitopsPromoteScript) { + const marker = `runtime_noop_decision="$(node - "$runtime_path" "$old_runtime_snapshot" /workspace/source/affected-services.json <<'NODE'\n`; + const start = gitopsPromoteScript.indexOf(marker); + assert.notEqual(start, -1, "missing runtime no-op decision script"); + const rest = gitopsPromoteScript.slice(start + marker.length); + const end = rest.indexOf("\nNODE\n)"); + assert.notEqual(end, -1, "missing runtime no-op decision terminator"); + return rest.slice(0, end); +} + +function runtimeWorkloadsFixture({ runtimeCommit, agentRunBundleCommit }) { + return { + items: [{ + kind: "Deployment", + metadata: { + name: "hwlab-cloud-api", + labels: { "hwlab.pikastech.local/source-commit": runtimeCommit }, + annotations: { "hwlab.pikastech.local/boot-commit": runtimeCommit } + }, + spec: { + template: { + metadata: { + labels: { + "hwlab.pikastech.local/source-commit": runtimeCommit, + "hwlab.pikastech.local/artifact-source-commit": runtimeCommit + }, + annotations: { "hwlab.pikastech.local/boot-commit": runtimeCommit } + }, + spec: { + containers: [{ + name: "hwlab-cloud-api", + env: [ + { name: "HWLAB_COMMIT_ID", value: runtimeCommit }, + { name: "HWLAB_GITOPS_SOURCE_COMMIT", value: runtimeCommit }, + { name: "HWLAB_CODE_AGENT_AGENTRUN_SOURCE_COMMIT", value: agentRunBundleCommit } + ] + }] + } + } + } + }] + }; +} + +async function runtimeNoopDecision(gitopsPromoteScript, { oldRuntime, newRuntime }) { + const script = extractRuntimeNoopDecisionScript(gitopsPromoteScript); + const root = await mkdtemp(path.join(os.tmpdir(), "hwlab-v02-runtime-noop-")); + try { + const oldDir = path.join(root, "old-runtime"); + const newDir = path.join(root, "new-runtime"); + const planPath = path.join(root, "affected-services.json"); + await mkdir(oldDir, { recursive: true }); + await mkdir(newDir, { recursive: true }); + await writeFile(path.join(oldDir, "workloads.json"), JSON.stringify(runtimeWorkloadsFixture(oldRuntime), null, 2)); + await writeFile(path.join(newDir, "workloads.json"), JSON.stringify(runtimeWorkloadsFixture(newRuntime), null, 2)); + await writeFile(planPath, JSON.stringify({ buildServices: [], rolloutServices: [] })); + const result = spawnSync(process.execPath, ["-", newDir, oldDir, planPath], { input: script, encoding: "utf8" }); + assert.equal(result.status, 0, result.stderr || result.stdout); + return result.stdout.trim(); + } finally { + await rm(root, { recursive: true, force: true }); + } +} + test("v02 render follows TypeScript runtime checks and does not self-patch bootstrap RBAC", async () => { const outDir = await mkdtemp(path.join(os.tmpdir(), "hwlab-v02-render-test-")); try { @@ -76,6 +140,28 @@ test("v02 render follows TypeScript runtime checks and does not self-patch boots assert.match(gitopsPromoteScript, /runtime-identity-only/u); assert.match(gitopsPromoteScript, /skipped-runtime-unchanged/u); assert.match(gitopsPromoteScript, /printf 'false' > \/tekton\/results\/runtime-ready-required/u); + assert.match(gitopsPromoteScript, /HWLAB_CODE_AGENT_AGENTRUN_SOURCE_COMMIT/u); + assert.match(gitopsPromoteScript, /semanticRuntimeCommitEnvNames\.has\(envName\)/u); + assert.equal(await runtimeNoopDecision(gitopsPromoteScript, { + oldRuntime: { + runtimeCommit: "1111111111111111111111111111111111111111", + agentRunBundleCommit: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + }, + newRuntime: { + runtimeCommit: "2222222222222222222222222222222222222222", + agentRunBundleCommit: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + } + }), "runtime-identity-only"); + assert.equal(await runtimeNoopDecision(gitopsPromoteScript, { + oldRuntime: { + runtimeCommit: "1111111111111111111111111111111111111111", + agentRunBundleCommit: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + }, + newRuntime: { + runtimeCommit: "2222222222222222222222222222222222222222", + agentRunBundleCommit: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + }), "runtime-required"); assert.match(gitopsPromoteScript, /argo_hard_refresh_v02\(\) \{/u); assert.match(gitopsPromoteScript, /argocd\.argoproj\.io\/refresh": "hard"/u); assert.match(gitopsPromoteScript, /applications\/" \+ encodeURIComponent\(application\) \+ "\?fieldManager=hwlab-v02-gitops-promote/u);