From 4eab0323d6cb3f7a4cf5227c52bea09bd02564a7 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Mon, 14 Sep 2026 12:30:53 +0200 Subject: [PATCH] Fix CI: npm test's glob pattern doesn't expand on Node 20 "tsx --test test/**/*.test.ts" worked locally (Node v22) and failed on the CI runner (node:20-alpine, Node v20) with: Could not find '.../server/test/**/*.test.ts' node --test only gained native glob-pattern CLI arguments around Node 21/22; on Node 20 the literal glob string is treated as a single filename and, unsurprisingly, not found. Same script, two Node majors, different behavior - not a shell/quoting issue (both runs go through tsx's own CLI, no shell glob expansion involved either way). Fixed by listing the four test files explicitly instead of relying on a glob whose CLI support turned out to vary across the exact two Node installs this project runs on (this dev machine, and node:20-alpine - the CI container and server/Dockerfile's runtime image, deliberately matched). engines.node is >=18, so relying on a 21/22-only feature was already a latent bug even before it showed up. Verified locally (all 25 tests still pass with the explicit list) - the actual node:20-alpine behavior will confirm on the next CI run. Co-Authored-By: Claude Sonnet 5 --- docs/architecture.md | 17 +++++++++++++++++ server/package.json | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/docs/architecture.md b/docs/architecture.md index 5389ab0..91499ce 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1088,6 +1088,23 @@ jobs clone sources by hand with `git init`/`fetch`/`checkout` rather than jobs don't share a filesystem, so each clones independently; `publish` only starts once `test` succeeds. +**A real failure on the very first two runs**, caught by actually watching +the pipeline rather than assuming green: `"test": "tsx --test +test/**/*.test.ts"` worked perfectly locally and failed on the runner with +`Could not find '.../test/**/*.test.ts'`, as if the literal glob string +had been handed to Node as a filename. It had - `node --test` gained +native glob-pattern CLI arguments only around Node 21/22, and this dev +machine's global `node` is v22, while the CI job (deliberately pinned to +`node:20-alpine`, matching `server/Dockerfile`'s runtime image) is v20 - +same script, two Node majors, one of which silently doesn't glob-expand +the argument at all and just looks for a file with `*` characters in its +literal name. Fixed by listing the four test files explicitly in the +script instead of trusting a glob to be interpreted the same way on every +Node version this project targets (`engines.node` is `>=18`) - a +one-time list-maintenance cost in exchange for not depending on a CLI +feature whose availability turned out to vary across the exact two Node +installs this project actually runs on. + Client: since esbuild bundles everything into one `app.js` (no more individually-importable view modules the way separate `