From 93d841206506b9192257536872076a0d82f51bed Mon Sep 17 00:00:00 2001 From: root Date: Wed, 22 Jul 2026 08:22:14 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=AF=86=E5=88=AB=20lane=20service=20?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E9=85=8D=E7=BD=AE=E5=8F=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/ci-plan.test.mjs | 36 ++++++++++++++++++++++++++++++++++++ scripts/src/ci-plan-lib.mjs | 13 ++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/scripts/ci-plan.test.mjs b/scripts/ci-plan.test.mjs index 04a61bf2..12c0c7bc 100644 --- a/scripts/ci-plan.test.mjs +++ b/scripts/ci-plan.test.mjs @@ -437,6 +437,42 @@ test("node CI planner scopes runtime config rendering to the changed service wit assert.equal(plan.ciCdPlan.noImageBuildReason, "runtime-config-only-change"); }); +test("v03 planner scopes lane service runtime overrides without image builds", async () => { + const selectedServices = ["hwlab-cloud-api", "hwlab-cloud-web", "hwlab-gateway"]; + const repo = await createFixtureRepo({ serviceIds: selectedServices }); + const deployPath = path.join(repo, "deploy/deploy.yaml"); + const deploy = await readStructuredFile(repo, deployPath); + deploy.lanes.v03.services = selectedServices.map((serviceId) => ({ serviceId, env: { RUNTIME_REVISION: "v1" } })); + await writeStructuredFile(repo, deployPath, deploy); + await git(repo, ["add", "deploy/deploy.yaml"]); + await git(repo, ["commit", "-m", "seed v03 runtime overrides"]); + + deploy.lanes.v03.services.find((service) => service.serviceId === "hwlab-cloud-api").env.RUNTIME_REVISION = "v2"; + deploy.lanes.v03.services.find((service) => service.serviceId === "hwlab-cloud-web").env.RUNTIME_REVISION = "v2"; + await writeStructuredFile(repo, deployPath, deploy); + await git(repo, ["add", "deploy/deploy.yaml"]); + await git(repo, ["commit", "-m", "change two v03 runtime overrides"]); + + const plan = await createCiPlan({ + repoRoot: repo, + lane: "v03", + baseRef: "HEAD~1", + targetRef: "HEAD", + artifactCatalogPath: "deploy/artifact-catalog.v03.json", + services: selectedServices + }); + + assert.deepEqual(plan.affectedServices, ["hwlab-cloud-api", "hwlab-cloud-web"]); + assert.deepEqual(plan.rolloutServices, ["hwlab-cloud-api", "hwlab-cloud-web"]); + assert.deepEqual(plan.buildServices, []); + assert.deepEqual(plan.rolloutWithoutImageBuildServices, ["hwlab-cloud-api", "hwlab-cloud-web"]); + assert.deepEqual(plan.reusedServices, ["hwlab-gateway"]); + assert.equal(plan.services.find((service) => service.serviceId === "hwlab-cloud-api").runtimeConfigChanged, true); + assert.equal(plan.services.find((service) => service.serviceId === "hwlab-cloud-web").runtimeConfigChanged, true); + assert.equal(plan.services.find((service) => service.serviceId === "hwlab-gateway").runtimeConfigChanged, false); + assert.equal(plan.ciCdPlan.noImageBuildReason, "runtime-config-only-change"); +}); + test("node CI planner keeps Tekton renderer changes out of runtime rollout scope", async () => { const repo = await createFixtureRepo(); await mkdir(path.join(repo, "scripts/src/gitops-render"), { recursive: true }); diff --git a/scripts/src/ci-plan-lib.mjs b/scripts/src/ci-plan-lib.mjs index 62e3e0f0..5615bd58 100644 --- a/scripts/src/ci-plan-lib.mjs +++ b/scripts/src/ci-plan-lib.mjs @@ -748,10 +748,21 @@ function serviceRuntimeConfigIdentity(deployJson, lane, serviceId) { healthPort: Number.isInteger(declaration.healthPort) ? declaration.healthPort : null, healthProbe: normalizeServiceHealthProbe(declaration.healthProbe), env: normalizeServiceEnv(declaration.env), - observable: declaration.observable === true + observable: declaration.observable === true, + baseRuntimeService: runtimeServiceConfigById(deployJson?.services, serviceId), + laneRuntimeService: runtimeServiceConfigById(laneConfig?.services, serviceId) }; } +function runtimeServiceConfigById(services, serviceId) { + if (!Array.isArray(services)) return null; + let match = null; + for (const service of services) { + if (service?.serviceId === serviceId) match = service; + } + return match; +} + export async function packageRuntimeFieldsChanged(repoRoot, baseRef, targetRef, filePath = "package.json") { const [before, after] = await Promise.all([ readJsonFromGit(repoRoot, baseRef, filePath, null),