From 05a6d13933f244e81d3f73fbc37323cb192d2f32 Mon Sep 17 00:00:00 2001 From: PoterPan Date: Tue, 9 Jun 2026 00:11:02 +0800 Subject: [PATCH] test: decouple R2/D1 bindings from wrangler.toml so forks that drop R2 keep green CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- packages/worker/test/env.d.ts | 5 ++++- packages/worker/test/smoke.test.ts | 5 +++++ packages/worker/vitest.config.ts | 9 +++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/worker/test/env.d.ts b/packages/worker/test/env.d.ts index 2e115dc..ce10fb9 100644 --- a/packages/worker/test/env.d.ts +++ b/packages/worker/test/env.d.ts @@ -8,7 +8,10 @@ declare global { namespace Cloudflare { interface Env extends AppEnv { TEST_MIGRATIONS: D1Migration[]; - BUCKET: R2Bucket; // tests always provide R2; override the app's optional binding + // The harness always injects R2 (vitest.config.ts `miniflare.r2Buckets`), so override + // the app's optional `BUCKET?` to non-optional here. R2-absent behavior is exercised by + // tests that locally set `env.BUCKET = undefined`. + BUCKET: R2Bucket; } } } diff --git a/packages/worker/test/smoke.test.ts b/packages/worker/test/smoke.test.ts index 38cf6ae..701369e 100644 --- a/packages/worker/test/smoke.test.ts +++ b/packages/worker/test/smoke.test.ts @@ -2,6 +2,11 @@ import { env } from "cloudflare:test"; import { describe, expect, it } from "vitest"; describe("test harness", () => { + // R2 is OPTIONAL in production (wrangler.toml's [[r2_buckets]] may be removed). The test + // harness guarantees BUCKET regardless by injecting it via vitest.config.ts `miniflare.r2Buckets` + // — decoupled from wrangler.toml — so the storage suite runs even on a fork that dropped R2. + // The R2-absent runtime path is covered separately by tests that set `env.BUCKET = undefined` + // (e.g. settle.test.ts, retention.test.ts, upload.test.ts, admin.test.ts). it("binds D1 and R2", () => { expect(env.DB).toBeDefined(); expect(env.BUCKET).toBeDefined(); diff --git a/packages/worker/vitest.config.ts b/packages/worker/vitest.config.ts index f680e5b..8b62dca 100644 --- a/packages/worker/vitest.config.ts +++ b/packages/worker/vitest.config.ts @@ -14,6 +14,15 @@ export default defineConfig(async () => { wrangler: { configPath: "./wrangler.toml" }, miniflare: { bindings: { TEST_MIGRATIONS: migrations }, + // Declare the Worker's bindings here, not via wrangler.toml, so the test + // harness is decoupled from deployment-specific config. R2 is OPTIONAL in + // production (wrangler.toml's [[r2_buckets]] may be removed — see env.ts + // `BUCKET?`), so a fork that drops it must still get a working test bucket; + // otherwise `env.BUCKET` is undefined and the storage suite breaks. miniflare + // options take precedence over (and merge with) the wrangler config, while + // compatibility_date/flags + vars still come from wrangler.toml. + d1Databases: ["DB"], + r2Buckets: ["BUCKET"], }, }), ],