From a8b8d48c3e5e558c7295db40e595ed6c5ae3e1c1 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Mon, 19 Oct 2026 16:29:27 +0100 Subject: [PATCH] [vite-plugin] Remove no-effect v1 backports Revert #16316, #16315, and #16290, which added only upstream Wrangler/Miniflare tests and plugin release notes. Keep the actual fixes already supplied by the dependency upgrades in #16289. --- .changeset/vite-v1-cancelled-rollback.md | 7 - .../vite-v1-occupied-port-diagnostics.md | 7 - .changeset/vite-v1-turborepo-hotkeys.md | 7 - .../__tests__/helpers/published-wrangler.ts | 76 ---------- .../src/__tests__/runtime-startup.spec.ts | 133 ------------------ .../src/__tests__/wrangler-rollback.spec.ts | 121 ---------------- .../src/__tests__/wrangler-turborepo.spec.ts | 53 ------- 7 files changed, 404 deletions(-) delete mode 100644 .changeset/vite-v1-cancelled-rollback.md delete mode 100644 .changeset/vite-v1-occupied-port-diagnostics.md delete mode 100644 .changeset/vite-v1-turborepo-hotkeys.md delete mode 100644 packages/vite-plugin-cloudflare/src/__tests__/helpers/published-wrangler.ts delete mode 100644 packages/vite-plugin-cloudflare/src/__tests__/runtime-startup.spec.ts delete mode 100644 packages/vite-plugin-cloudflare/src/__tests__/wrangler-rollback.spec.ts delete mode 100644 packages/vite-plugin-cloudflare/src/__tests__/wrangler-turborepo.spec.ts diff --git a/.changeset/vite-v1-cancelled-rollback.md b/.changeset/vite-v1-cancelled-rollback.md deleted file mode 100644 index 24bb8b48eb5..00000000000 --- a/.changeset/vite-v1-cancelled-rollback.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@cloudflare/vite-plugin": patch ---- - -Keep cancelled Wrangler rollbacks from reporting a successful deployment - -The bundled Wrangler release now stops after declining the changed-secrets confirmation, without printing a success message or a new current version. The compatible Wrangler dependency is supplied by the earlier remote-token retry backport. diff --git a/.changeset/vite-v1-occupied-port-diagnostics.md b/.changeset/vite-v1-occupied-port-diagnostics.md deleted file mode 100644 index 98b36d401e1..00000000000 --- a/.changeset/vite-v1-occupied-port-diagnostics.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@cloudflare/vite-plugin": patch ---- - -Update Miniflare to preserve occupied-port diagnostics across stderr chunks - -Use `miniflare@5.20261012.1-beta` so local development reports the complete address-in-use error even when workerd splits its diagnostic across stderr writes. diff --git a/.changeset/vite-v1-turborepo-hotkeys.md b/.changeset/vite-v1-turborepo-hotkeys.md deleted file mode 100644 index 4b1da65b729..00000000000 --- a/.changeset/vite-v1-turborepo-hotkeys.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@cloudflare/vite-plugin": patch ---- - -Hide unusable Wrangler development hotkeys under Turborepo stream output - -The bundled Wrangler release hides shortcuts when Turborepo does not forward keyboard input, while retaining them in its interactive terminal UI. The compatible Wrangler dependency is supplied by the earlier remote-token retry backport; Vite's own shortcuts remain unchanged. diff --git a/packages/vite-plugin-cloudflare/src/__tests__/helpers/published-wrangler.ts b/packages/vite-plugin-cloudflare/src/__tests__/helpers/published-wrangler.ts deleted file mode 100644 index bb58be33f0a..00000000000 --- a/packages/vite-plugin-cloudflare/src/__tests__/helpers/published-wrangler.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { spawn } from "node:child_process"; -import { once } from "node:events"; -import { createRequire } from "node:module"; -import { onTestFinished, vi } from "vitest"; - -const require = createRequire(import.meta.url); - -// Pipes let the tests drive real prompts without adding a native PTY dependency. -const terminalSetup = ` -Object.defineProperty(process.stdin, "isTTY", { value: true }); -Object.defineProperty(process.stdout, "isTTY", { value: true }); -Object.defineProperty(process.stderr, "isTTY", { value: true }); -process.stdin.setRawMode = () => process.stdin; -`; - -/** Starts the installed Wrangler CLI with deterministic interactive input. */ -export function startPublishedWrangler( - args: string[], - cwd: string, - env: NodeJS.ProcessEnv = {} -) { - const child = spawn( - process.execPath, - [ - "--import", - `data:text/javascript,${encodeURIComponent(terminalSetup)}`, - require.resolve("wrangler"), - ...args, - ], - { - cwd, - env: { - ...process.env, - CI: "false", - CF_PAGES: "", - WORKERS_CI: "", - WRANGLER_SEND_METRICS: "false", - WRANGLER_HOME: cwd, - WRANGLER_LOG_PATH: cwd, - ...env, - }, - } - ); - let output = ""; - child.stdout.setEncoding("utf8").on("data", (chunk: string) => { - output += chunk; - }); - child.stderr.setEncoding("utf8").on("data", (chunk: string) => { - output += chunk; - }); - const closed = once(child, "close"); - onTestFinished(async () => { - if (child.exitCode === null && child.signalCode === null) { - child.kill(); - } - await closed; - }); - - return { - child, - closed, - get output() { - return output; - }, - async waitForOutput(text: string) { - await vi.waitFor( - () => { - if (!output.includes(text)) { - throw new Error(`Waiting for ${JSON.stringify(text)}:\n${output}`); - } - }, - { timeout: 20_000, interval: 20 } - ); - }, - }; -} diff --git a/packages/vite-plugin-cloudflare/src/__tests__/runtime-startup.spec.ts b/packages/vite-plugin-cloudflare/src/__tests__/runtime-startup.spec.ts deleted file mode 100644 index 122e0977a17..00000000000 --- a/packages/vite-plugin-cloudflare/src/__tests__/runtime-startup.spec.ts +++ /dev/null @@ -1,133 +0,0 @@ -import childProcess from "node:child_process"; -import { PassThrough } from "node:stream"; -import { Runtime } from "miniflare"; -import { test, vi } from "vitest"; - -/** Simulates workerd exiting after emitting the given stderr chunks. */ -function mockRuntimeFailure(chunks: string[]) { - return vi.spyOn(childProcess, "spawn").mockImplementation(() => { - const stdin = new PassThrough(); - const stdout = new PassThrough(); - const stderr = new PassThrough(); - const control = new PassThrough(); - const process = Object.assign(new childProcess.ChildProcess(), { - stdin, - stdout, - stderr, - stdio: [stdin, stdout, stderr, control], - kill: () => true, - }); - stdin.on("finish", () => { - // Separate writes give the startup buffer deterministic chunk boundaries. - for (const chunk of chunks) { - stderr.write(chunk); - } - stderr.end(); - control.end(); - process.emit("exit", 1, null); - }); - return process; - }); -} - -const failures = [ - { - name: "Rust socket error", - stderr: 'Socket "entry": bind(): Address already in use (os error 98)\n', - address: "127.0.0.1:8787", - }, - { - name: "structured Rust socket error", - stderr: `${JSON.stringify({ - timestamp: 1700000000000, - level: "error", - message: 'Socket "entry": bind(): Address already in use (os error 48)', - })}\n`, - address: "127.0.0.1:8787", - }, - { - name: "Windows socket error", - stderr: - 'Socket "entry": bind(): Only one usage of each socket address (protocol/network address/port) is normally permitted. (os error 10048)\n', - address: "127.0.0.1:8787", - }, - { - name: "C++ fatal bind error", - stderr: - "*** Fatal uncaught kj::Exception: rust/cxx/kj-rs-io/ffi.rs:209: failed: bind(): Address already in use (os error 48)\n", - address: undefined, - }, - { - name: "legacy C++ socket error", - stderr: - "kj/async-io-unix.c++:1: failed: Address already in use; toString() = [::1]:8787; stack: 7ff6a1b2c3d4\n", - address: "[::1]:8787", - }, - { - name: "socket error after another bind failure", - stderr: - 'Socket "other": bind(): Permission denied (os error 13)\nSocket "entry": bind(): Address already in use (os error 98)\n', - address: "127.0.0.1:8787", - }, -]; - -/** Exercises the published Miniflare startup contract used by Vite plugin v1. */ -function startRuntime(runtime: Runtime) { - return runtime.updateConfig( - Buffer.alloc(0), - { - entryAddress: "127.0.0.1:8787", - loopbackAddress: "127.0.0.1:1234", - requiredSockets: ["entry"], - handleStructuredLogs() {}, - }, - [], - new AbortController().signal - ); -} - -test.for(failures)( - "diagnoses $name regardless of stderr chunk boundaries", - async ({ stderr, address }, { expect, onTestFinished }) => { - const runtime = new Runtime(); - onTestFinished(() => runtime.dispose()); - const chunks: string[] = []; - const spawn = mockRuntimeFailure(chunks); - onTestFinished(() => spawn.mockRestore()); - const where = address === undefined ? "" : ` (${address})`; - - // Try every possible split, including splits within a socket name or address. - for (let split = 0; split <= stderr.length; split++) { - chunks.splice( - 0, - chunks.length, - stderr.slice(0, split), - stderr.slice(split) - ); - await expect(startRuntime(runtime)).rejects.toMatchObject({ - code: "ERR_ADDRESS_IN_USE", - message: `Address already in use${where}. Please check that you are not already running a server on this address or specify a different port with --port.`, - }); - } - } -); - -test("preserves stderr for other startup failures", async ({ - expect, - onTestFinished, -}) => { - const stderr = 'Socket "entry": bind(): Permission denied (os error 13)'; - const spawn = mockRuntimeFailure([ - stderr.slice(0, 20), - stderr.slice(20), - "\n", - ]); - onTestFinished(() => spawn.mockRestore()); - const runtime = new Runtime(); - onTestFinished(() => runtime.dispose()); - - await expect(startRuntime(runtime)).rejects.toMatchObject({ - code: "ERR_RUNTIME_FAILURE", - message: expect.stringContaining(`Runtime stderr:\n${stderr}`), - }); -}); diff --git a/packages/vite-plugin-cloudflare/src/__tests__/wrangler-rollback.spec.ts b/packages/vite-plugin-cloudflare/src/__tests__/wrangler-rollback.spec.ts deleted file mode 100644 index ce3e5785077..00000000000 --- a/packages/vite-plugin-cloudflare/src/__tests__/wrangler-rollback.spec.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { once } from "node:events"; -import { mkdtemp, writeFile } from "node:fs/promises"; -import { createServer } from "node:http"; -import { tmpdir } from "node:os"; -import { join } from "node:path"; -import { removeDir } from "@cloudflare/workers-utils"; -import { test } from "vitest"; -import { startPublishedWrangler } from "./helpers/published-wrangler"; - -test.for([false, true])( - "reports rollback success only when changed secrets are accepted (%s)", - async (acceptSecrets, { expect, onTestFinished }) => { - const root = await mkdtemp(join(tmpdir(), "vite-v1-rollback-")); - onTestFinished(() => removeDir(root)); - await writeFile( - join(root, "wrangler.json"), - JSON.stringify({ name: "rollback-test", account_id: "test-account" }) - ); - const deployments: (string | null)[] = []; - const unexpected: string[] = []; - const server = createServer((request, response) => { - request.resume(); - const url = new URL(request.url ?? "/", "http://localhost"); - let result: unknown; - if (request.method === "GET" && url.pathname.endsWith("/deployments")) { - result = { - deployments: [ - { - id: "current-deployment", - created_on: "2026-10-15T00:00:00Z", - source: "api", - strategy: "percentage", - versions: [{ version_id: "current-version", percentage: 100 }], - }, - ], - }; - } else if ( - request.method === "GET" && - url.pathname.includes("/versions/") - ) { - result = { - id: url.pathname.split("/").at(-1), - number: 1, - metadata: {}, - resources: { bindings: [], script: { handlers: ["fetch"] } }, - }; - } else if ( - request.method === "POST" && - url.pathname.endsWith("/deployments") - ) { - const force = url.searchParams.get("force"); - deployments.push(force); - if (force !== "true") { - response.writeHead(400, { "Content-Type": "application/json" }); - response.end( - JSON.stringify({ - success: false, - errors: [ - { - code: 10220, - message: - "The following secrets have changed: SECRET_ONE, SECRET_TWO", - }, - ], - }) - ); - return; - } - result = {}; - } else { - unexpected.push(`${request.method} ${url.pathname}`); - response.writeHead(404); - response.end(); - return; - } - response.writeHead(200, { "Content-Type": "application/json" }); - response.end( - JSON.stringify({ success: true, errors: [], messages: [], result }) - ); - }); - server.listen(0, "127.0.0.1"); - await once(server, "listening"); - onTestFinished(() => { - server.closeAllConnections(); - return new Promise((resolve) => server.close(() => resolve())); - }); - const address = server.address(); - if (address === null || typeof address === "string") { - throw new Error("Expected a TCP address"); - } - const wrangler = startPublishedWrangler( - ["rollback", "rollback-version"], - root, - { - CLOUDFLARE_API_TOKEN: "test-token", - CLOUDFLARE_API_BASE_URL: `http://127.0.0.1:${address.port}`, - } - ); - await wrangler.waitForOutput("Please provide an optional message"); - wrangler.child.stdin.write("\r"); - await wrangler.waitForOutput("Are you sure you want to deploy"); - wrangler.child.stdin.write("y\r"); - await wrangler.waitForOutput("Please confirm you wish to continue"); - wrangler.child.stdin.end(acceptSecrets ? "y\r" : "n\r"); - await wrangler.closed; - - expect(wrangler.child.exitCode, wrangler.output).toBe(0); - expect(unexpected).toEqual([]); - expect(deployments).toEqual(acceptSecrets ? [null, "true"] : [null]); - if (acceptSecrets) { - expect(wrangler.output).toContain("has been deployed to 100% of traffic"); - expect(wrangler.output).toContain("Current Version ID: rollback-version"); - } else { - expect(wrangler.output).toContain("Aborting rollback"); - expect(wrangler.output).not.toContain( - "has been deployed to 100% of traffic" - ); - expect(wrangler.output).not.toContain("Current Version ID:"); - } - } -); diff --git a/packages/vite-plugin-cloudflare/src/__tests__/wrangler-turborepo.spec.ts b/packages/vite-plugin-cloudflare/src/__tests__/wrangler-turborepo.spec.ts deleted file mode 100644 index 97966265e01..00000000000 --- a/packages/vite-plugin-cloudflare/src/__tests__/wrangler-turborepo.spec.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { mkdtemp, writeFile } from "node:fs/promises"; -import { tmpdir } from "node:os"; -import { join } from "node:path"; -import { removeDir } from "@cloudflare/workers-utils"; -import { test } from "vitest"; -import { startPublishedWrangler } from "./helpers/published-wrangler"; - -test.for([ - { turboHash: "test-hash", turboIsTui: "", interactive: false }, - { turboHash: "test-hash", turboIsTui: "false", interactive: false }, - { turboHash: "test-hash", turboIsTui: "true", interactive: true }, - { turboHash: "", turboIsTui: "", interactive: true }, -])( - "shows Wrangler hotkeys only when input is forwarded ($turboHash/$turboIsTui)", - async ( - { turboHash, turboIsTui, interactive }, - { expect, onTestFinished } - ) => { - const root = await mkdtemp(join(tmpdir(), "vite-v1-turborepo-")); - onTestFinished(() => removeDir(root)); - await writeFile( - join(root, "wrangler.json"), - JSON.stringify({ - name: "turborepo-test", - main: "index.js", - compatibility_date: "2026-10-15", - }) - ); - await writeFile( - join(root, "index.js"), - "export default { fetch() { return new Response('ok'); } };" - ); - const wrangler = startPublishedWrangler( - ["dev", "--ip", "127.0.0.1", "--port", "0", "--inspector-port", "0"], - root, - { TURBO_HASH: turboHash, TURBO_IS_TUI: turboIsTui } - ); - await wrangler.waitForOutput("Ready on"); - - for (const hotkey of [ - "open a browser", - "open devtools", - "clear console", - "to exit", - ]) { - if (interactive) { - expect(wrangler.output).toContain(hotkey); - } else { - expect(wrangler.output).not.toContain(hotkey); - } - } - } -);