Skip to content

test: decouple R2/D1 bindings from wrangler.toml (forks that drop R2 keep green CI)#6

Merged
poterpan merged 1 commit into
mainfrom
fix/test-r2-decouple
Jun 8, 2026
Merged

test: decouple R2/D1 bindings from wrangler.toml (forks that drop R2 keep green CI)#6
poterpan merged 1 commit into
mainfrom
fix/test-r2-decouple

Conversation

@poterpan

@poterpan poterpan commented Jun 8, 2026

Copy link
Copy Markdown
Owner

Problem

R2 is optional in production — wrangler.toml's [[r2_buckets]] block carries a comment saying it can be removed, and env.ts types BUCKET? accordingly. But the Vitest pool read bindings straight from wrangler.toml (wrangler: { configPath: "./wrangler.toml" }). A fork that followed the "remove R2" instruction got env.BUCKET === undefined, and 10 storage-suite tests failed — even though the deployed Worker degraded gracefully.

Our own CI never caught this because the committed wrangler.toml keeps the R2 binding, so we never exercised the path we tell forkers to take. (Reported by a downstream fork; confirmed by reproducing locally.)

Fix

Declare the Worker's bindings (DB, BUCKET) via miniflare options in vitest.config.ts instead of relying on wrangler.toml for them:

miniflare: {
  bindings: { TEST_MIGRATIONS: migrations },
  d1Databases: ["DB"],
  r2Buckets: ["BUCKET"],
},

Rationale: binding shape is a code contract (src references env.DB/env.BUCKET), so the test harness should own it — not the deployment-specific, fork-editable wrangler.toml. compatibility_date/compatibility_flags + [vars] still come from wrangler.toml (preserves prod-fidelity). miniflare options take precedence over and merge with the wrangler config, so this is conflict-free when wrangler.toml also defines the bindings.

The R2-absent runtime path stays covered by the existing env.BUCKET = undefined tests (settle / retention / upload / admin). Added clarifying comments to smoke.test.ts and env.d.ts explaining why R2 is always present in tests.

Verification

Reproduced the fork's exact failure by commenting out [[r2_buckets]] locally:

  • Pre-fix, R2 removed: 8 files / 10 tests fail (env.BUCKET undefined) — matches the fork's CI.
  • Post-fix, R2 removed: 179/179 pass.
  • Post-fix, R2 present (our config): 179/179 pass, typecheck clean.

Independent review (Codex) confirmed the diagnosis and that miniflare.r2Buckets is the correct option with safe merge semantics.

…2 keep green CI

R2 is optional in production (wrangler.toml [[r2_buckets]] may be removed —
env.ts BUCKET?), but the Vitest pool read bindings straight from wrangler.toml
(configPath). A fork that followed the 'remove R2' comment got env.BUCKET ===
undefined and 10 storage-suite tests failed, even though the deployed Worker
degraded gracefully. Our own CI never caught it because the committed
wrangler.toml keeps the R2 binding.

Declare DB + BUCKET via miniflare options instead, so the harness owns the
binding shape (code contract) while compatibility_date/flags + vars still come
from wrangler.toml. R2-absent runtime behavior stays covered by the existing
env.BUCKET=undefined tests; clarify smoke.test.ts/env.d.ts on why R2 is always
present in tests.

Verified by commenting out [[r2_buckets]] locally: pre-fix 10 failures
reproduced the fork's CI; post-fix 179/179 pass with and without R2.
@poterpan poterpan merged commit c08e631 into main Jun 8, 2026
2 checks passed
@poterpan poterpan deleted the fix/test-r2-decouple branch June 8, 2026 16:32
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