diff --git a/scripts/g14-gitops-render.mjs b/scripts/g14-gitops-render.mjs index 355a105d..86d38c83 100644 --- a/scripts/g14-gitops-render.mjs +++ b/scripts/g14-gitops-render.mjs @@ -1865,10 +1865,10 @@ function planArtifactsTask({ serviceIds = defaultServiceIds } = {}) { }; } -function perServiceBuildTask(serviceId) { +function perServiceBuildTask(serviceId, { runAfter = ["plan-artifacts"] } = {}) { return { name: buildTaskName(serviceId), - runAfter: ["plan-artifacts"], + runAfter, workspaces: [{ name: "source", workspace: "source" }], taskSpec: { params: [ @@ -2144,9 +2144,12 @@ function runtimeReadyTask({ profile = "dev" } = {}) { function imagePublishTaskSet(args = { lane: "g14" }) { const serviceIds = serviceIdsForLane(args.lane); + const buildTasks = serviceIds.map((serviceId, index) => perServiceBuildTask(serviceId, { + runAfter: args.lane === "v02" && index > 0 ? [buildTaskName(serviceIds[index - 1])] : ["plan-artifacts"] + })); return [ planArtifactsTask({ serviceIds }), - ...serviceIds.map(perServiceBuildTask), + ...buildTasks, collectArtifactsTask({ serviceIds }) ]; } diff --git a/scripts/g14-gitops-render.test.ts b/scripts/g14-gitops-render.test.ts index 0e9121ab..e6c114d0 100644 --- a/scripts/g14-gitops-render.test.ts +++ b/scripts/g14-gitops-render.test.ts @@ -5,6 +5,12 @@ import os from "node:os"; import path from "node:path"; import test from "node:test"; +function taskByName(pipeline, name) { + const task = pipeline.spec.tasks.find((item) => item.name === name); + assert.ok(task, `missing task ${name}`); + return task; +} + 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 { @@ -21,6 +27,7 @@ test("v02 render follows TypeScript runtime checks and does not self-patch boots assert.equal(render.status, 0, render.stderr || render.stdout); const pipeline = await readFile(path.join(outDir, "tekton-v02", "pipeline.yaml"), "utf8"); + const pipelineJson = JSON.parse(pipeline); assert.match(pipeline, /127\.0\.0\.1:5000\/hwlab\/hwlab-ci-node-tools:node22-alpine-bun-v1/u); assert.match(pipeline, /node scripts\/run-bun\.mjs test cmd\/hwlab-codex-api-responses-forwarder\/main\.test\.ts/u); assert.doesNotMatch(pipeline, /cmd\/hwlab-codex-api-responses-forwarder\/main\.mjs/u); @@ -38,6 +45,24 @@ test("v02 render follows TypeScript runtime checks and does not self-patch boots assert.doesNotMatch(pipeline, new RegExp(`build-${serviceId}`, "u")); } + const retainedServiceIds = [ + "hwlab-cloud-api", + "hwlab-cloud-web", + "hwlab-agent-mgr", + "hwlab-agent-worker", + "hwlab-device-pod", + "hwlab-gateway", + "hwlab-edge-proxy", + "hwlab-cli", + "hwlab-agent-skills" + ]; + for (let index = 0; index < retainedServiceIds.length; index += 1) { + const serviceId = retainedServiceIds[index]; + const task = taskByName(pipelineJson, `build-${serviceId}`); + const expectedRunAfter = index === 0 ? ["plan-artifacts"] : [`build-${retainedServiceIds[index - 1]}`]; + assert.deepEqual(task.runAfter, expectedRunAfter); + } + const workloads = await readFile(path.join(outDir, "runtime-v02", "workloads.yaml"), "utf8"); const services = await readFile(path.join(outDir, "runtime-v02", "services.yaml"), "utf8"); for (const serviceId of removedServiceIds) {