From 9abce28b1da8d7b5f221010bf37195bf1a2046a6 Mon Sep 17 00:00:00 2001 From: Ramon Bartl Date: Tue, 15 Sep 2026 09:24:46 +0200 Subject: [PATCH 1/2] Fix the pnpm workspace file I broke CI with My fault, from #267. The pnpm-workspace.yaml I added to approve esbuild's build script broke pnpm install in CI: ERROR packages field missing or empty pnpm 9, which the workflow pins, treats any pnpm-workspace.yaml as a workspace declaration and refuses to install without a packages field. pnpm 12, which I have locally, does not. I tested the install on my machine, saw it succeed, and shipped a file that only works on the version I happened to have. The file now carries both keys, one for each version: packages: ["."] so pnpm 9 is satisfied and the layout is unchanged, and ignoredBuiltDependencies so pnpm 10+ stops refusing an install that skipped a build script. Skipping it is deliberate. esbuild's script places a prebuilt binary that neither the build nor the tests need, verified by wiping node_modules, installing without it, and running pnpm build and pnpm test. The approval in #267 was me reacting to a warning without checking whether it meant anything. The workflow also runs the frontend tests now. #267 added them and never wired them in, so the job that failed would not have caught a broken test either. --- .github/workflows/test.yml | 3 +++ frontend/pnpm-workspace.yaml | 28 +++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 97d03c0a..bc72ba8f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -48,3 +48,6 @@ jobs: - name: Type check and build run: cd frontend && pnpm build + + - name: Run tests + run: cd frontend && pnpm test diff --git a/frontend/pnpm-workspace.yaml b/frontend/pnpm-workspace.yaml index a2ac8c79..09758f62 100644 --- a/frontend/pnpm-workspace.yaml +++ b/frontend/pnpm-workspace.yaml @@ -1,6 +1,24 @@ -# esbuild ships a prebuilt binary and needs its install -# script to put it in place; vitest will not start without -# it. Approved explicitly because pnpm blocks build scripts -# by default, which is the right default. +# Both keys are load-bearing, for different pnpm versions. +# +# packages: pnpm 9, which CI pins, treats any +# pnpm-workspace.yaml as a workspace declaration and +# refuses to install without this field: +# +# ERROR packages field missing or empty +# +# "." is this package itself, so the install layout is +# unchanged. +# +# ignoredBuiltDependencies: pnpm 10 and later refuse to +# finish an install that skipped a package's build script +# (ERR_PNPM_IGNORED_BUILDS) unless told the skip is +# deliberate. esbuild's script places a prebuilt binary +# that neither the build nor the tests need: verified with +# a clean install that skipped it, followed by pnpm build +# and pnpm test, both green. +packages: + - . allowBuilds: - esbuild: true + esbuild: set this to true or false +ignoredBuiltDependencies: + - esbuild From e1afe910d8b9244b959ca5b0d025462ff9791f7b Mon Sep 17 00:00:00 2001 From: Ramon Bartl Date: Tue, 15 Sep 2026 09:27:13 +0200 Subject: [PATCH 2/2] Run CI on Node 22, which jsdom needs The frontend tests I wired in one commit ago fail on the runner: TypeError: webidl.util.markAsUncloneable is not a function at new CacheStorage undici@8.10.2/.../cachestorage.js at jsdom@30.0.1/lib/api.js jsdom 30, which vitest pulls in, declares engines ^22.22.2 || ^24.15.0 || >=26.0.0, and undici 8 under it wants >=22.19.0. CI ran Node 20, where the import dies with a message that names neither Node nor a version. Both workflows move to 22. The runners had already annotated the previous run to say 20 is deprecated and that actions are being forced onto 24, so this was due anyway. frontend/package.json gains an engines field so the requirement is visible where someone would look for it, rather than only in a transitive dependency's metadata. --- .github/workflows/build-desktop.yml | 9 ++++++++- .github/workflows/test.yml | 9 ++++++++- frontend/package.json | 3 +++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-desktop.yml b/.github/workflows/build-desktop.yml index 75e27209..d3796d56 100644 --- a/.github/workflows/build-desktop.yml +++ b/.github/workflows/build-desktop.yml @@ -38,7 +38,14 @@ jobs: - name: Set up Node uses: actions/setup-node@v4 with: - node-version: "20" + # 22, not 20. jsdom 30 (via vitest) declares + # engines ^22.22.2 || ^24.15.0 || >=26.0.0, and on + # 20 it fails at import with + # "webidl.util.markAsUncloneable is not a + # function" rather than anything that names a Node + # version. The runners also warn that 20 is + # deprecated and force actions onto 24. + node-version: "22" - name: Set up pnpm uses: pnpm/action-setup@v4 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bc72ba8f..7b256012 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -36,7 +36,14 @@ jobs: - name: Set up Node uses: actions/setup-node@v4 with: - node-version: "20" + # 22, not 20. jsdom 30 (via vitest) declares + # engines ^22.22.2 || ^24.15.0 || >=26.0.0, and on + # 20 it fails at import with + # "webidl.util.markAsUncloneable is not a + # function" rather than anything that names a Node + # version. The runners also warn that 20 is + # deprecated and force actions onto 24. + node-version: "22" - name: Set up pnpm uses: pnpm/action-setup@v4 diff --git a/frontend/package.json b/frontend/package.json index fe93161f..981eb210 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -2,6 +2,9 @@ "name": "kaisho-frontend", "private": true, "version": "2.9.1", + "engines": { + "node": ">=22.22.2" + }, "type": "module", "scripts": { "dev": "vite",