[PR #1098] [MERGED] fix(deploy): resolve wrangler .CMD shim on Windows #1094

Closed
opened 2026-05-06 13:11:57 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/1098
Author: @piffie
Created: 5/6/2026
Status: Merged
Merged: 5/6/2026
Merged by: @james-elicx

Base: mainHead: fix/windows-wrangler-shim


📝 Commits (5)

  • 8495545 fix(deploy): resolve wrangler .CMD shim on Windows (#1095)
  • 4238f72 Apply suggestion from @ask-bonk[bot]
  • 8442afd style: format deploy.ts
  • e0a7045 Merge remote-tracking branch 'origin/main' into pr-1098-fix2
  • 638fced test(app-elements): include artifactCompatibility in legacy-payload round-trip expectation

📊 Changes

3 files changed (+81 additions, -5 deletions)

View changed files

📝 packages/vinext/src/deploy.ts (+32 -5)
📝 tests/app-elements.test.ts (+1 -0)
📝 tests/deploy.test.ts (+48 -0)

📄 Description

Summary

Fixes #1095vinext deploy on Windows fails with spawnSync wrangler ENOENT because runWranglerDeploy invokes the bare-name node_modules/.bin/wrangler file. On Windows that file is a Unix shebang script with no PATHEXT extension, so CreateProcess() (used by execFileSync) refuses to execute it. The .CMD shim sitting next to it is the actual Windows-executable.

Change

  • Extract resolveWranglerBin(root, platform?) from runWranglerDeploy.
  • On win32 prefer .bin/wrangler.CMD, fall back to .bin/wrangler (covers oddball PMs that don't generate a .CMD shim).
  • On other platforms behavior is unchanged: .bin/wrangler only.
  • The unfound-fallback path is also platform-appropriate so the resulting ENOENT error message points at the actual file Node would have tried to spawn.
  • platform is an injected parameter (defaulting to process.platform) so the helper is unit-testable without mutating globals.

Considered Option 2 (cross-spawn) and Option 3 (shell: true) from the bug report. Option 1 keeps the dep surface unchanged and matches the issue tracker's recommendation; happy to switch to cross-spawn if maintainers prefer.

Tests

Five new cases in tests/deploy.test.ts → describe("resolveWranglerBin"):

  • non-Windows uses bare name
  • Windows prefers .CMD when both files exist
  • Windows falls back to bare name when no .CMD exists
  • monorepo hoisting works on Windows (walks up to ancestor node_modules)
  • not-found fallback path is platform-appropriate

pnpm test tests/deploy.test.ts — 215 passed (210 existing + 5 new).
pnpm exec vp check packages/vinext/src/deploy.ts tests/deploy.test.ts — clean (formatting, lint, types).

Test plan

  • Targeted Vitest run on tests/deploy.test.ts passes (Windows 11, Node 24.13.0, pnpm 10)
  • vp check clean on changed files
  • Manual verification on the original reproducer (Next.js 15 App Router on pnpm Turborepo workspace): vinext deploy --preview now invokes wrangler successfully on Windows
  • CI Linux/macOS runs (regression check: bare name still resolves)
  • If a Windows runner exists or gets added (issue mentions one was added in #31), exercising vinext deploy --dry-run there would catch any future regression

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/1098 **Author:** [@piffie](https://github.com/piffie) **Created:** 5/6/2026 **Status:** ✅ Merged **Merged:** 5/6/2026 **Merged by:** [@james-elicx](https://github.com/james-elicx) **Base:** `main` ← **Head:** `fix/windows-wrangler-shim` --- ### 📝 Commits (5) - [`8495545`](https://github.com/cloudflare/vinext/commit/8495545dab42ad669d6868115f451517cf4aa746) fix(deploy): resolve wrangler .CMD shim on Windows (#1095) - [`4238f72`](https://github.com/cloudflare/vinext/commit/4238f7202de12e2d30f93498e6b79a54ce5c0ef2) Apply suggestion from @ask-bonk[bot] - [`8442afd`](https://github.com/cloudflare/vinext/commit/8442afdd9f28e508c7a1c05d0413d9f680a21705) style: format deploy.ts - [`e0a7045`](https://github.com/cloudflare/vinext/commit/e0a704597ba57eb27bc2092b8ce7e7506c6519d2) Merge remote-tracking branch 'origin/main' into pr-1098-fix2 - [`638fced`](https://github.com/cloudflare/vinext/commit/638fced7dd428df3a9819a393634e3c6e5146fdd) test(app-elements): include artifactCompatibility in legacy-payload round-trip expectation ### 📊 Changes **3 files changed** (+81 additions, -5 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/deploy.ts` (+32 -5) 📝 `tests/app-elements.test.ts` (+1 -0) 📝 `tests/deploy.test.ts` (+48 -0) </details> ### 📄 Description ## Summary Fixes #1095 — `vinext deploy` on Windows fails with `spawnSync wrangler ENOENT` because `runWranglerDeploy` invokes the bare-name `node_modules/.bin/wrangler` file. On Windows that file is a Unix shebang script with no PATHEXT extension, so `CreateProcess()` (used by `execFileSync`) refuses to execute it. The `.CMD` shim sitting next to it is the actual Windows-executable. ## Change - Extract `resolveWranglerBin(root, platform?)` from `runWranglerDeploy`. - On `win32` prefer `.bin/wrangler.CMD`, fall back to `.bin/wrangler` (covers oddball PMs that don't generate a `.CMD` shim). - On other platforms behavior is unchanged: `.bin/wrangler` only. - The unfound-fallback path is also platform-appropriate so the resulting ENOENT error message points at the actual file Node would have tried to spawn. - `platform` is an injected parameter (defaulting to `process.platform`) so the helper is unit-testable without mutating globals. Considered Option 2 (`cross-spawn`) and Option 3 (`shell: true`) from the bug report. Option 1 keeps the dep surface unchanged and matches the issue tracker's recommendation; happy to switch to `cross-spawn` if maintainers prefer. ## Tests Five new cases in `tests/deploy.test.ts → describe("resolveWranglerBin")`: - non-Windows uses bare name - Windows prefers `.CMD` when both files exist - Windows falls back to bare name when no `.CMD` exists - monorepo hoisting works on Windows (walks up to ancestor `node_modules`) - not-found fallback path is platform-appropriate `pnpm test tests/deploy.test.ts` — 215 passed (210 existing + 5 new). `pnpm exec vp check packages/vinext/src/deploy.ts tests/deploy.test.ts` — clean (formatting, lint, types). ## Test plan - [x] Targeted Vitest run on `tests/deploy.test.ts` passes (Windows 11, Node 24.13.0, pnpm 10) - [x] `vp check` clean on changed files - [x] Manual verification on the original reproducer (Next.js 15 App Router on pnpm Turborepo workspace): `vinext deploy --preview` now invokes wrangler successfully on Windows - [ ] CI Linux/macOS runs (regression check: bare name still resolves) - [ ] If a Windows runner exists or gets added (issue mentions one was added in #31), exercising `vinext deploy --dry-run` there would catch any future regression 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 13:11:57 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#1094
No description provided.