From d0b3f24e4f55d920a78333366f36d64ba0a3dab4 Mon Sep 17 00:00:00 2001 From: Aditya Choudhari Date: Mon, 18 May 2026 16:39:31 -0400 Subject: [PATCH 1/2] fix: "false" is treated as valid CEL --- apps/api/src/routes/v1/workspaces/deployments.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/api/src/routes/v1/workspaces/deployments.ts b/apps/api/src/routes/v1/workspaces/deployments.ts index 038319016..f0ba7077d 100644 --- a/apps/api/src/routes/v1/workspaces/deployments.ts +++ b/apps/api/src/routes/v1/workspaces/deployments.ts @@ -22,7 +22,7 @@ import { listDeploymentVariablesByDeploymentRouter } from "./deployment-variable const PLAN_TTL_MS = 60 * 60 * 1000; const parseSelector = (raw: string | null | undefined): string | undefined => { - if (raw == null || raw === "false") return undefined; + if (raw == null) return undefined; return raw; }; From 3b090cdb86c076c75dbf686714f41a4f35c5b1f2 Mon Sep 17 00:00:00 2001 From: Aditya Choudhari Date: Mon, 18 May 2026 16:58:06 -0400 Subject: [PATCH 2/2] add test --- e2e/tests/api/deployments.spec.ts | 62 +++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/e2e/tests/api/deployments.spec.ts b/e2e/tests/api/deployments.spec.ts index 2f5362e61..eb932842f 100644 --- a/e2e/tests/api/deployments.spec.ts +++ b/e2e/tests/api/deployments.spec.ts @@ -178,6 +178,68 @@ test.describe("Deployment API", () => { ); }); + test("should return resourceSelector verbatim when written as 'false'", async ({ + api, + workspace, + }) => { + const name = `deploy-rs-false-${faker.string.alphanumeric(8)}`; + const createRes = await api.POST( + "/v1/workspaces/{workspaceId}/deployments", + { + params: { path: { workspaceId: workspace.id } }, + body: { name, slug: name, resourceSelector: "false" }, + }, + ); + expect(createRes.response.status).toBe(202); + const deploymentId = createRes.data!.id; + + const getRes = await api.GET( + "/v1/workspaces/{workspaceId}/deployments/{deploymentId}", + { + params: { path: { workspaceId: workspace.id, deploymentId } }, + }, + ); + + expect(getRes.response.status).toBe(200); + expect(getRes.data!.deployment.resourceSelector).toBe("false"); + + await api.DELETE( + "/v1/workspaces/{workspaceId}/deployments/{deploymentId}", + { params: { path: { workspaceId: workspace.id, deploymentId } } }, + ); + }); + + test("should default resourceSelector to 'false' when omitted on create", async ({ + api, + workspace, + }) => { + const name = `deploy-rs-omit-${faker.string.alphanumeric(8)}`; + const createRes = await api.POST( + "/v1/workspaces/{workspaceId}/deployments", + { + params: { path: { workspaceId: workspace.id } }, + body: { name, slug: name }, + }, + ); + expect(createRes.response.status).toBe(202); + const deploymentId = createRes.data!.id; + + const getRes = await api.GET( + "/v1/workspaces/{workspaceId}/deployments/{deploymentId}", + { + params: { path: { workspaceId: workspace.id, deploymentId } }, + }, + ); + + expect(getRes.response.status).toBe(200); + expect(getRes.data!.deployment.resourceSelector).toBe("false"); + + await api.DELETE( + "/v1/workspaces/{workspaceId}/deployments/{deploymentId}", + { params: { path: { workspaceId: workspace.id, deploymentId } } }, + ); + }); + test("should create a deployment with a custom jobAgentSelector", async ({ api, workspace,