From 1da5ea1df6d13609b635e010403d0791f6893d6a Mon Sep 17 00:00:00 2001 From: Sawyer Date: Thu, 20 Aug 2026 16:44:44 -0700 Subject: [PATCH] CI: hub env-stashing wrote the string "undefined", un-skipping DB-gated suites MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three apps/hub suites cleared environment variables with `process.env[key] = undefined`. Node — and Bun from 1.4 onward, the version CI's `bun-version: latest` now resolves to — coerces that to the *string* "undefined" rather than removing the key, so after the first memory-mount test every later read of DATABASE_URL and EMBED_BASE_URL saw a truthy value. That poisoned the whole `bun test` process for @workbench/hub, which runs in the `checks` job with no Postgres service: - `mountMemory` accepted "undefined" as a configured EMBED_BASE_URL and went on to migrate, so the two tests asserting the unconfigured path died on a connection instead. - Every DB-gated `describe.skipIf(...)`/`?? ""` gate un-skipped and handed postgres.js an unparseable URL, which falls back to its localhost:5432 default — hence `ECONNREFUSED ::1:5432` *and* `127.0.0.1:5432` on both stacks, with no service anywhere to refuse them. Clear the keys for real with `Reflect.deleteProperty` (dynamic `delete` is lint-banned). With Bun 1.4's coercion simulated locally the suite reproduces CI exactly — 151 tests, 17 fail; after the fix it is 154 tests, 134 pass, 20 skip, 0 fail. --- apps/hub/src/artifacts-mount.test.ts | 4 +++- apps/hub/src/memory-mount.test.ts | 8 ++++++-- apps/hub/src/memory-workflow-routes.test.ts | 4 +++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/apps/hub/src/artifacts-mount.test.ts b/apps/hub/src/artifacts-mount.test.ts index 6237d0f73..27c93abfc 100644 --- a/apps/hub/src/artifacts-mount.test.ts +++ b/apps/hub/src/artifacts-mount.test.ts @@ -24,7 +24,9 @@ type EnvKey = (typeof KEYS)[number]; const saved: Partial> = {}; function clearEnvKey(key: EnvKey): void { - process.env[key] = undefined; + // Assigning `undefined` would store the string "undefined"; the key has to + // go. `Reflect.deleteProperty` because eslint forbids dynamic `delete`. + Reflect.deleteProperty(process.env, key); } function stashEnv(): void { diff --git a/apps/hub/src/memory-mount.test.ts b/apps/hub/src/memory-mount.test.ts index 4f061c0d6..8c33708e2 100644 --- a/apps/hub/src/memory-mount.test.ts +++ b/apps/hub/src/memory-mount.test.ts @@ -17,8 +17,12 @@ type EnvKey = (typeof KEYS)[number]; const saved: Partial> = {}; function clearEnvKey(key: EnvKey): void { - // Prefer assignment over `delete process.env[key]` — eslint forbids dynamic delete. - process.env[key] = undefined; + // Must actually remove the key: `process.env[key] = undefined` stores the + // *string* "undefined" (Bun >= 1.4 matches Node here), which reads as a + // configured value and makes every DATABASE_URL/EMBED_BASE_URL gate in this + // app's suites fire against postgres.js's localhost:5432 default. + // `Reflect.deleteProperty` because eslint forbids dynamic `delete`. + Reflect.deleteProperty(process.env, key); } afterEach(() => { diff --git a/apps/hub/src/memory-workflow-routes.test.ts b/apps/hub/src/memory-workflow-routes.test.ts index b4d38b6a1..6fbf75d08 100644 --- a/apps/hub/src/memory-workflow-routes.test.ts +++ b/apps/hub/src/memory-workflow-routes.test.ts @@ -43,7 +43,9 @@ type EnvKey = (typeof KEYS)[number]; const saved: Partial> = {}; function clearEnvKey(key: EnvKey): void { - process.env[key] = undefined; + // Assigning `undefined` would store the string "undefined"; the key has to + // go. `Reflect.deleteProperty` because eslint forbids dynamic `delete`. + Reflect.deleteProperty(process.env, key); } function stashEnv(): void {