From 6b9a69b4f67e145239e580c04510081c07dfed60 Mon Sep 17 00:00:00 2001 From: Cedric Vidal Date: Tue, 3 Nov 2026 14:20:58 -0800 Subject: [PATCH 1/3] fix(compose): remove the gateway development CPU quota Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- CONTRIBUTING.md | 8 ++++ docker-compose.dev.yml | 18 ++++----- docs/architecture/ai-gateway.md | 11 +++++- scripts/docker-compose.test.ts | 70 +++++++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+), 10 deletions(-) create mode 100644 scripts/docker-compose.test.ts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a90006f0f..ca11ea73e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -87,6 +87,14 @@ pnpm dev:coder-acp-copilot # A single worker natively (pnpm dev:@gateway:18000` (session ID embedded as userinfo) and `DEV_PROXY_API_URL=http://gateway:18000`. ## Kubernetes Deployment diff --git a/scripts/docker-compose.test.ts b/scripts/docker-compose.test.ts new file mode 100644 index 000000000..08c107434 --- /dev/null +++ b/scripts/docker-compose.test.ts @@ -0,0 +1,70 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { spawnSync } from "node:child_process"; +import { describe, expect, it } from "vitest"; + +interface ComposeService { + cpus?: number; + depends_on?: Record; + healthcheck?: { + test?: string[]; + start_period?: string; + }; + mem_limit?: string; + volumes?: Array<{ + source?: string; + target: string; + }>; +} + +interface ComposeConfig { + services: Record; +} + +describe("development Docker Compose configuration", () => { + it("keeps the gateway cold-build resources and Copilot worker dependency", () => { + const result = spawnSync( + "docker", + [ + "compose", + "-f", + "docker-compose.yml", + "-f", + "docker-compose.dev.yml", + "--profile", + "copilot", + "config", + "--format", + "json", + ], + { + encoding: "utf8", + env: { ...process.env, GITHUB_TOKEN: process.env.GITHUB_TOKEN ?? "" }, + }, + ); + + expect(result.status, result.stderr).toBe(0); + + const config = JSON.parse(result.stdout) as ComposeConfig; + const gateway = config.services.gateway; + const copilotWorker = config.services["coder-acp-copilot"]; + + expect(gateway.cpus).toBeUndefined(); + expect(gateway.mem_limit).toBe(String(2 * 1024 ** 3)); + expect(gateway.healthcheck?.start_period).toBe("10m0s"); + expect(gateway.healthcheck?.test).toEqual([ + "CMD-SHELL", + "wget -qO- http://127.0.0.1:18000/health || exit 1", + ]); + expect(gateway.volumes).toContainEqual( + expect.objectContaining({ + source: "gateway_target", + target: "/build/target", + }), + ); + expect(copilotWorker.depends_on?.gateway?.condition).toBe( + "service_healthy", + ); + }); +}); From a73e0ec5715a74aa4f53c4cab6c3227dbf60ac57 Mon Sep 17 00:00:00 2001 From: Cedric Vidal Date: Tue, 3 Nov 2026 17:06:58 -0800 Subject: [PATCH 2/3] fix(website): add missing license headers Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- website/src/styles/contributions.css | 4 +++- website/src/styles/contributors.css | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/website/src/styles/contributions.css b/website/src/styles/contributions.css index 6aa468603..98f3bd382 100644 --- a/website/src/styles/contributions.css +++ b/website/src/styles/contributions.css @@ -1,7 +1,9 @@ /* * Copyright (c) Microsoft Corporation. * Licensed under the MIT License. - * + */ + +/* * Shared presentation for website contribution data: status messages, * count pills, cards, and development-only sample labels. */ diff --git a/website/src/styles/contributors.css b/website/src/styles/contributors.css index 5e75ab0ed..03ef9015a 100644 --- a/website/src/styles/contributors.css +++ b/website/src/styles/contributors.css @@ -1,7 +1,9 @@ /* * Copyright (c) Microsoft Corporation. * Licensed under the MIT License. - * + */ + +/* * Contributors (). An avatar wall on the * landing page and a card grid on the Community > Contribute page. Shares * the card, message and sample-tag styles in contributions.css. From 5a621ee1f32785e657179ccccb178991f7146ef0 Mon Sep 17 00:00:00 2001 From: Cedric Vidal Date: Wed, 4 Nov 2026 13:11:32 -0800 Subject: [PATCH 3/3] test(compose): skip render check without Docker Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- scripts/docker-compose.test.ts | 92 +++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 41 deletions(-) diff --git a/scripts/docker-compose.test.ts b/scripts/docker-compose.test.ts index 08c107434..096b29c5f 100644 --- a/scripts/docker-compose.test.ts +++ b/scripts/docker-compose.test.ts @@ -22,49 +22,59 @@ interface ComposeConfig { services: Record; } +// Keep the default unit suite runnable without Docker while preserving strict +// merged-configuration validation whenever Compose is available. +const dockerComposeAvailable = + spawnSync("docker", ["compose", "version"], { + encoding: "utf8", + }).status === 0; + describe("development Docker Compose configuration", () => { - it("keeps the gateway cold-build resources and Copilot worker dependency", () => { - const result = spawnSync( - "docker", - [ - "compose", - "-f", - "docker-compose.yml", - "-f", - "docker-compose.dev.yml", - "--profile", - "copilot", - "config", - "--format", - "json", - ], - { - encoding: "utf8", - env: { ...process.env, GITHUB_TOKEN: process.env.GITHUB_TOKEN ?? "" }, - }, - ); + it.skipIf(!dockerComposeAvailable)( + "keeps the gateway cold-build resources and Copilot worker dependency", + () => { + const result = spawnSync( + "docker", + [ + "compose", + "-f", + "docker-compose.yml", + "-f", + "docker-compose.dev.yml", + "--profile", + "copilot", + "config", + "--format", + "json", + ], + { + encoding: "utf8", + env: { ...process.env, GITHUB_TOKEN: process.env.GITHUB_TOKEN ?? "" }, + }, + ); - expect(result.status, result.stderr).toBe(0); + expect(result.status, result.stderr).toBe(0); - const config = JSON.parse(result.stdout) as ComposeConfig; - const gateway = config.services.gateway; - const copilotWorker = config.services["coder-acp-copilot"]; + const config = JSON.parse(result.stdout) as ComposeConfig; + const gateway = config.services.gateway; + const copilotWorker = config.services["coder-acp-copilot"]; - expect(gateway.cpus).toBeUndefined(); - expect(gateway.mem_limit).toBe(String(2 * 1024 ** 3)); - expect(gateway.healthcheck?.start_period).toBe("10m0s"); - expect(gateway.healthcheck?.test).toEqual([ - "CMD-SHELL", - "wget -qO- http://127.0.0.1:18000/health || exit 1", - ]); - expect(gateway.volumes).toContainEqual( - expect.objectContaining({ - source: "gateway_target", - target: "/build/target", - }), - ); - expect(copilotWorker.depends_on?.gateway?.condition).toBe( - "service_healthy", - ); - }); + expect(gateway.cpus).toBeUndefined(); + expect(gateway.mem_limit).toBe(String(2 * 1024 ** 3)); + expect(gateway.healthcheck?.start_period).toBe("10m0s"); + expect(gateway.healthcheck?.test).toEqual([ + "CMD-SHELL", + "wget -qO- http://127.0.0.1:18000/health || exit 1", + ]); + expect(gateway.volumes).toContainEqual( + expect.objectContaining({ + source: "gateway_target", + target: "/build/target", + }), + ); + expect(copilotWorker.depends_on?.gateway?.condition).toBe( + "service_healthy", + ); + }, + ); });