From b2dfe814454cf2acee5f25192524cd7ba26cf966 Mon Sep 17 00:00:00 2001 From: Madraka Date: Tue, 20 Oct 2026 21:16:24 +0300 Subject: [PATCH] fix(cli): deploy the admin Worker under its own name in Workers Builds Workers Builds sets WRANGLER_CI_OVERRIDE_NAME to the connected Worker; wrangler then deployed the admin Worker under the site Worker's name, so the first Deploy to Cloudflare run served Studio at the site's address and created no admin Worker. cloudhal deploy now drops the override (and WRANGLER_CI_MATCH_TAG) and names each Worker itself. Co-Authored-By: Claude Opus 5.5 Signed-off-by: Madraka --- .changeset/workers-builds-override-name.md | 5 ++++ docs/guides/deploy-button.md | 4 +++ packages/cli/src/cloudflare/wrangler.ts | 12 +++++++- packages/cli/test/wrangler-ci-env.test.ts | 35 ++++++++++++++++++++++ 4 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 .changeset/workers-builds-override-name.md create mode 100644 packages/cli/test/wrangler-ci-env.test.ts diff --git a/.changeset/workers-builds-override-name.md b/.changeset/workers-builds-override-name.md new file mode 100644 index 00000000..8d2eb56a --- /dev/null +++ b/.changeset/workers-builds-override-name.md @@ -0,0 +1,5 @@ +--- +"@cloudhal/cli": patch +--- + +The Deploy to Cloudflare button deploys the admin Worker under its own name. Workers Builds sets `WRANGLER_CI_OVERRIDE_NAME` to the Worker a build is connected to, and wrangler then deploys every config under that name, so the admin Worker overwrote the site Worker (the site's address served Studio). `cloudhal deploy` no longer passes `WRANGLER_CI_OVERRIDE_NAME` or `WRANGLER_CI_MATCH_TAG` to wrangler; it names each Worker itself. diff --git a/docs/guides/deploy-button.md b/docs/guides/deploy-button.md index 6035d74b..c1dd8b65 100644 --- a/docs/guides/deploy-button.md +++ b/docs/guides/deploy-button.md @@ -43,3 +43,7 @@ Start from `npm create cloudhal@latest`, then: - commit `cloudhal.json` and a root `wrangler.jsonc` that names the site Worker, a `DB` D1 database (placeholder id `00000000-0000-0000-0000-000000000000`) and a `BLOBS` R2 bucket - remove the `build` script (Workers Builds would run it before `deploy`), keep `"deploy": "cloudhal deploy"` - commit a lockfile and a `.node-version` of `24`. The CLI runs on Node 24. + +## Before 0.3.2: the site Worker shows Studio + +Workers Builds sets `WRANGLER_CI_OVERRIDE_NAME` to the Worker a build is connected to. Before 0.3.2, `cloudhal deploy` passed it on to wrangler, so the admin Worker was uploaded under the site Worker's name. The site's address then served Studio, and no `-admin` Worker existed. To fix a deployment made that way, bump `@cloudhal/*` in your copy of the template to 0.3.2 or later and push. The next build deploys both Workers under their own names. diff --git a/packages/cli/src/cloudflare/wrangler.ts b/packages/cli/src/cloudflare/wrangler.ts index 6e9983f7..a044dff2 100644 --- a/packages/cli/src/cloudflare/wrangler.ts +++ b/packages/cli/src/cloudflare/wrangler.ts @@ -70,7 +70,17 @@ export function wranglerRunner( return async (args, { cwd, quiet }) => { const dir = await mkdtemp(path.join(os.tmpdir(), "cloudhal-wrangler-")); const outputFile = path.join(dir, "output.ndjson"); - const { VITEST: _v, NODE_ENV: _n, ...env } = process.env; + // Workers Builds sets WRANGLER_CI_OVERRIDE_NAME (and WRANGLER_CI_MATCH_TAG) to the one Worker + // the build is connected to; wrangler then deploys every config under that name. `cloudhal + // deploy` names each Worker itself (the site keeps the connected name), so the admin Worker + // would otherwise overwrite the site. Seen on the first Deploy to Cloudflare button run. + const { + VITEST: _v, + NODE_ENV: _n, + WRANGLER_CI_OVERRIDE_NAME: _ciName, + WRANGLER_CI_MATCH_TAG: _ciTag, + ...env + } = process.env; try { const result = await new Promise<{ code: number; stdout: string; stderr: string }>( (resolve) => { diff --git a/packages/cli/test/wrangler-ci-env.test.ts b/packages/cli/test/wrangler-ci-env.test.ts new file mode 100644 index 00000000..047ff409 --- /dev/null +++ b/packages/cli/test/wrangler-ci-env.test.ts @@ -0,0 +1,35 @@ +import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises"; +import os from "node:os"; +import path from "node:path"; +import { afterAll, describe, expect, it } from "vitest"; +import { wranglerRunner } from "../src/cloudflare/wrangler.ts"; + +describe("wranglerRunner in Workers Builds", () => { + let dir: string; + afterAll(async () => { + if (dir) await rm(dir, { recursive: true, force: true }); + }); + + it("does not pass the build's Worker-name override to wrangler", async () => { + dir = await mkdtemp(path.join(os.tmpdir(), "cloudhal-wrangler-env-")); + await writeFile(path.join(dir, "package.json"), "{}"); + const pkg = path.join(dir, "node_modules/wrangler"); + await mkdir(path.join(pkg, "bin"), { recursive: true }); + await writeFile(path.join(pkg, "package.json"), '{"name":"wrangler","version":"4.151.0"}'); + // A stand-in wrangler that prints the variables a real one would read. + await writeFile( + path.join(pkg, "bin/wrangler.js"), + "process.stdout.write(JSON.stringify({ name: process.env.WRANGLER_CI_OVERRIDE_NAME ?? null, tag: process.env.WRANGLER_CI_MATCH_TAG ?? null, ci: process.env.WORKERS_CI ?? null }));", + ); + const saved = { ...process.env }; + process.env.WRANGLER_CI_OVERRIDE_NAME = "my-blog-site"; + process.env.WRANGLER_CI_MATCH_TAG = "tag123"; + process.env.WORKERS_CI = "1"; + try { + const r = await wranglerRunner(dir)(["deploy"], { cwd: dir, quiet: true }); + expect(JSON.parse(r.stdout)).toEqual({ name: null, tag: null, ci: "1" }); + } finally { + process.env = saved; + } + }); +});