Skip to content

ci: one deploy command that suits both toolchains - #445

Merged
oddharsh merged 1 commit into
mainfrom
ci/wrangler-bridge
Aug 20, 2026
Merged

oddharsh merged 1 commit into
mainfrom
ci/wrangler-bridge

Conversation

@oddharsh

Copy link
Copy Markdown
Owner

Lands .github/deploy-wrangler.sh so the Workers Builds dashboard can hold one command string that works on both main (pnpm) and the bun branch (#443).

No dashboard change is required by this PR, and infra.json is deliberately untouched. Merging this changes nothing about how anything deploys today; it just puts the script on main so the dashboard can be pointed at it as a separate, reversible step.

Why a script rather than a command

The dashboard holds a single string per trigger, and the two trees cannot share an invocation:

  • pnpm exec wrangler refuses on a bun tree. pnpm reads packageManager and exits with This project is configured to use bun (reproduced on pnpm 11.22.0; the build image ships 10.11.1, which enforces the same field).
  • bun …/wrangler.js cannot run on a pnpm tree in the image, which installs bun only when the tree asks for it.

So without this, the dashboard would have to be edited at the exact moment #443 merges, with every other branch's build broken on one side of the switch.

Three decisions worth reviewing

The lockfile decides, not PATH. The image preinstalls a bun of its own, so probing command -v bun would quietly run main's production deploy under a bun this tree never asked for.

It takes no opinion on wrangler's arguments. Everything after the script name passes through, so versions upload and both provisioning flags stay in the dashboard string where check-infra.mjs already reads them. That check needs no change.

It runs wrangler's entry file, not bun x wrangler. Measured 2026-08-18 with node replaced by a stub exiting 127: bun x --no-install wrangler invokes node through the #!/usr/bin/env node shebang and fails, while running the entry directly stays inside bun.

It also never fetches: npx/bunx/dlx resolve missing binaries from the registry (gotcha 29), which on the one path that publishes production means deploying with a wrangler nobody pinned.

Tested by running it

Fixture trees with stub binaries cover both branches plus the three loud failures: no lockfile, a missing wrangler entry, and no arguments. Control: breaking the lockfile branch fails the test by name (✖ the deploy bridge picks its invocation from the lockfile).

Also exercised against this tree for real, where it resolves pnpm exec wrangler and prints 4.123.0.

The sequence after this merges

  1. this PR (script only) — safe, changes no behaviour
  2. dashboard: point both commands at bash .github/deploy-wrangler.sh versions upload --x-provision=false --x-auto-create=false
  3. a follow-up PR updating infra.json's two strings

Between 2 and 3, infra:check reports drift on main and on any open PR, which is the documented dashboard-first cost. The follow-up PR's own CI is green, because its tree declares what the dashboard holds.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 18, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
aadhar-sh 1df8cde Aug 18 2026, 06:39 PM

@github-actions

Copy link
Copy Markdown
Contributor

Wire-size diff vs merge base

74e5d7f → d1858dd

Brotli q11, the quality the edge serves. Every number here is deterministic:
an unchanged file produces no row. Advisory — this check fails on nothing.

Client assets

No change. 21 files, 75.15 KiB Brotli total.

Pages

No change. 48 files, 502.05 KiB Brotli total.

Worker bundle

No change. 229.72 KiB gzip.

Dictionary deltas (pd/)

No change. 144 deltas, 451.39 KiB total.

@oddharsh
oddharsh marked this pull request as draft August 18, 2026 03:30
@oddharsh

Copy link
Copy Markdown
Owner Author

Converting to draft along with #443: the toolchain stays pnpm + node for now, so merging this would put a script on main that nothing calls.

It stays open because it is still the right shape for the day the migration resumes. The transition it exists for is real whenever main is a pnpm tree and a branch is a bun tree, which is exactly the window between #443 merging and the dashboard being flipped. Nothing in it is bun-1.4-specific.

@oddharsh

Copy link
Copy Markdown
Owner Author

Rebased onto main after #453 moved scripts/ to tools/. Git followed the rename, so the two bridge tests landed in tools/contract-tests.mjs with no manual resolution; the script itself lives under .github/ and was untouched by the move.

Both tests still pass by name, and test, lint, typecheck and build are green.

Still a draft on purpose: the toolchain stays pnpm and node, so pointing the dashboard at this script is not something to do yet. It merges the day the bun migration resumes.

@oddharsh
oddharsh force-pushed the ci/wrangler-bridge branch from de48ea5 to ad2d42c Compare August 18, 2026 15:32
Workers Builds holds a SINGLE command string per trigger, and it has to work on
whatever branch is being built. `main` is a pnpm tree; #443 makes it a bun tree,
and the two cannot share an invocation:

  pnpm exec wrangler        REFUSES on a bun tree. pnpm reads packageManager and
                            exits "This project is configured to use bun"
                            (reproduced on pnpm 11.22.0; the image ships 10.11.1,
                            which enforces the same field)
  bun .../wrangler.js       cannot run on a pnpm tree in the image, which
                            installs bun only when the tree asks for it

Without this, the dashboard string can only ever suit one branch, so the
migration would need the dashboard edited at the exact moment it merges with
every other branch's build broken on one side of the switch.

The LOCKFILE decides, not what is on PATH: the image preinstalls a bun of its
own, so probing `command -v bun` would quietly run main's production deploy
under a bun this tree never asked for.

It takes NO opinion on wrangler's arguments. Everything after the script name is
passed through, so `versions upload` and both provisioning flags stay in the
dashboard string where check-infra.mjs already reads them, and that check needs
no change.

It never fetches. npx/bunx/dlx resolve missing binaries from the registry
(gotcha 29), which on the one path that publishes production means deploying
with a wrangler nobody pinned. A test greps for those tokens rather than for a
phrase, since the sweep that closed that hole missed `npx` as a quoted argument.

It runs wrangler's ENTRY FILE rather than `bun x wrangler`: measured 2026-08-18
with node replaced by a stub exiting 127, `bun x --no-install wrangler` invokes
node through the `#!/usr/bin/env node` shebang and fails, while the entry stays
inside bun.

TESTED BY RUNNING IT against fixture trees with stub binaries: both branches,
plus the three loud failures (no lockfile, missing wrangler entry, no
arguments). Control run: breaking the lockfile branch fails the test by name.

No dashboard change is required by this commit. It lands the script so the
dashboard CAN be pointed at it, which is a separate step, with infra.json's
strings following after.
@oddharsh
oddharsh force-pushed the ci/wrangler-bridge branch from ad2d42c to 1df8cde Compare August 18, 2026 18:38
@oddharsh

Copy link
Copy Markdown
Owner Author

Rebased onto main after the TypeScript conversions (#459, #460).

One conflict, in tools/contract-tests.mjs: both sides appended a test block to the end of the suite, so the resolution is a union rather than a choice. The union initially dropped the quarantine test's closing });, which sat exactly on the conflict boundary — node --check caught it as Unexpected end of input, and all three tests pass now:

✔ every @ts-nocheck in the Worker is declared, and every declaration is real
✔ the deploy bridge picks its invocation from the lockfile
✔ the deploy bridge never resolves wrangler from the registry

Still a draft on purpose. The toolchain is pnpm and node, so pointing the dashboard at this script is not something to do yet; it merges the day the bun migration resumes.

@oddharsh
oddharsh marked this pull request as ready for review August 20, 2026 14:46
@oddharsh
oddharsh merged commit 2778c72 into main Aug 20, 2026
5 checks passed
@oddharsh
oddharsh deleted the ci/wrangler-bridge branch August 20, 2026 14:46
oddharsh added a commit that referenced this pull request Aug 20, 2026
Records what the dashboard runs, so infra:check stops reading drift. The
wrapper landed in #445 and is dormant until the dashboard points at it.

HOLD THIS UNTIL THE DASHBOARD IS FLIPPED. check-infra.mjs compares these
strings against the live dashboard values with an exact match, and validate
is a required check, so landing this first fails on drift it invented
itself and blocks its own merge. Dashboard first, strings second.

Both tree-tier assertions still hold: the two provisioning flags are
present, and it is still a `versions upload` so a publish moves no traffic.

MAINTENANCE.md's historical rollout recipe keeps its `pnpm exec` spelling.
That passage records the sequence used in 2026-08-04 and rewriting it would
falsify what was typed at the time.

Co-authored-by: Aadharsh Pannirselvam <19518661+oddharsh@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant