diff --git a/modules/build-agent/Dockerfile b/modules/build-agent/Dockerfile index 971f3f26..8abeaa19 100644 --- a/modules/build-agent/Dockerfile +++ b/modules/build-agent/Dockerfile @@ -5,9 +5,10 @@ ARG ALPINE_BASE # **The source is not vendored here.** builder's actual code — cmd/mesh-builder, internal/builder, # internal/catalogue — lives in the mesh-controller repository, the same control plane it is one # half of. This module ships the packaging, not a second copy of the source, so the build context -# is the mesh-controller repository root (declared under build.artifacts[].context), and this +# is the mesh-controller repository (declared under build.artifacts[].context), and this # Dockerfile compiles ./cmd/mesh-builder from it — the same shape route-proxy already uses for the -# same reason. +# same reason. The build seat hands it only that program's build source (novox/hq ADR 0267, the +# artifact's `compiles`): a merge elsewhere in that repository does not move this image. FROM ${GO_BASE} AS build WORKDIR /src COPY go.mod go.sum ./ diff --git a/modules/build-agent/module.json b/modules/build-agent/module.json index a7539ad3..87a37dbb 100644 --- a/modules/build-agent/module.json +++ b/modules/build-agent/module.json @@ -79,6 +79,7 @@ "name": "server", "kind": "image", "from": "Dockerfile", + "compiles": "cmd/mesh-builder", "context": { "seat": "git", "repository": "novox/mesh-controller", diff --git a/modules/gitea/client.ts b/modules/gitea/client.ts index f242683f..06a87020 100644 --- a/modules/gitea/client.ts +++ b/modules/gitea/client.ts @@ -362,6 +362,13 @@ export class GiteaClient { paths.push(name); const status = String(f?.status ?? ""); if (status === "deleted" || status === "removed") removed.push(name); + // **A renamed file is said under both names** (novox/hq ADR 0267, issue 363): its old path is gone, and + // a module whose build source held it changed even though the new path is elsewhere. + const previous = String(f?.previous_filename ?? ""); + if (previous !== "" && previous !== name) { + paths.push(previous); + removed.push(previous); + } } if (files.length === 0 || files.length < pageSize) return { paths, removed, truncated: false }; if (paths.length >= most) return { paths, removed, truncated: true }; diff --git a/modules/gitea/test/pages.test.ts b/modules/gitea/test/pages.test.ts index 063cf324..b4bed7e0 100644 --- a/modules/gitea/test/pages.test.ts +++ b/modules/gitea/test/pages.test.ts @@ -71,3 +71,21 @@ test("a lookup the forge refuses is thrown, not read as no module", async () => await assert.rejects(client.moduleDirsAt("novox", "mesh-catalog", "abc", ["modules/x/y.ts"])); server.close(); }); + +test("a renamed file is said under its old name too, as gone (novox/hq ADR 0267)", async () => { + const server = createServer((req, res) => { + const page = Number(new URL(req.url ?? "", "http://x").searchParams.get("page") ?? "1"); + res.setHeader("content-type", "application/json"); + res.end(JSON.stringify(page > 1 ? [] : [ + { filename: "internal/elsewhere/moved.go", previous_filename: "internal/broker/moved.go", status: "renamed" }, + { filename: "README.md", status: "changed" }, + ])); + }); + await new Promise((r) => server.listen(0, r)); + const port = (server.address() as any).port; + const client = new GiteaClient(`http://127.0.0.1:${port}`, "t"); + const got = await client.listPullFiles("novox", "mesh-controller", 7); + server.close(); + assert.deepEqual(got.paths, ["internal/elsewhere/moved.go", "internal/broker/moved.go", "README.md"]); + assert.deepEqual(got.removed, ["internal/broker/moved.go"], "the old name is gone from the tree"); +}); diff --git a/modules/route-proxy/Dockerfile b/modules/route-proxy/Dockerfile index 45593a7e..b556c2f6 100644 --- a/modules/route-proxy/Dockerfile +++ b/modules/route-proxy/Dockerfile @@ -5,7 +5,10 @@ ARG GO_BASE=golang:1.25 # **The proxy source is not vendored here.** The canonical proxy — the contract written as something # that runs — lives in the mesh-controller repository at examples/route-proxy (novox/hq 08-connectivity # §3). This module ships the *packaging*, not a second copy of the contract, so the build context is -# the mesh-controller repository root, and this Dockerfile compiles ./examples/route-proxy from it. +# the mesh-controller repository, and this Dockerfile compiles ./examples/route-proxy from it. The build seat +# hands it only that program's build source — its import closure, go.mod, go.sum and the vendored packages +# it uses (novox/hq ADR 0267, the artifact's `compiles`) — so a merge elsewhere in that repository does not +# move this image, and a COPY of anything outside it fails by name. # # docker build -f mesh-catalog/modules/route-proxy/Dockerfile \ # -t mesh-route-proxy:development /mesh-controller diff --git a/modules/route-proxy/module.json b/modules/route-proxy/module.json index 38444a45..548695a4 100644 --- a/modules/route-proxy/module.json +++ b/modules/route-proxy/module.json @@ -188,6 +188,7 @@ "name": "server", "kind": "image", "from": "Dockerfile", + "compiles": "examples/route-proxy", "context": { "seat": "git", "repository": "novox/mesh-controller",