From c28d2206579c681e438d8a3be776b89c2e956f46 Mon Sep 17 00:00:00 2001 From: EtienneLescot Date: Fri, 4 Sep 2026 22:34:24 +0200 Subject: [PATCH] build: pin electron exactly, so packaging works without a second declaration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `npm run build:win` failed at electron-builder in any checkout without its own `node_modules/electron` — a git worktree, typically, where Node's resolution walks up and finds the parent's copy but electron-builder looks only at the project's: Electron version "^41.2.1" is a range, not a fixed version. electron-builder needs an exact version because it downloads the binaries for one release. Given the range and no local install, it refuses. Pinned rather than answered with `electronVersion` in electron-builder.json5, because that would make the version two facts that have to agree and nothing would notice when they stopped. The dependency declaration is the one place the version is written; electron-builder reads it there. The caret was already inert where it mattered: the lockfile pins 41.2.1 and every CI job installs through .github/actions/setup, which runs `npm ci`. It only ever applied to a bare `npm install` — and an unattended Electron bump is what we want least here, since the packaging config carries facts held against one release by hand (`minimumSystemVersion` against Electron 41's own `LSMinimumSystemVersion`) and AGENTS.md records behaviour observed on 41.2.1 exactly. build-and-packaging.md already claimed the version was exact; now it is. A comment in electron-builder.json5 says why there is no `electronVersion` there and names the error, so the next person to hit it adds `npm ci` rather than the second source of truth. Regenerating the lockfile also dropped `@mediapipe/selfie_segmentation`, which left package.json in 6e5ffa91 when segmentation moved into the compositor and was never regenerated out of the lock. Nothing imports it; `npm ci` was downloading it in every job. Verified: `npm run build:win`, unmodified, in a worktree with no `node_modules/electron` and no override flag — installer produced. --- electron-builder.json5 | 11 +++++++++++ package-lock.json | 10 ++-------- package.json | 2 +- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/electron-builder.json5 b/electron-builder.json5 index 58f3e0742..dafe8c690 100644 --- a/electron-builder.json5 +++ b/electron-builder.json5 @@ -10,6 +10,17 @@ "**/*.node" ], "productName": "Openscreen", + // There is deliberately no `electronVersion` here. electron-builder needs an EXACT + // version because it downloads the binaries for one release, and it takes that from + // package.json's `electron` devDependency, which is pinned without a caret for this + // reason. Setting it here as well would make the version two facts that have to agree, + // and nothing would notice when they stopped. + // + // The error that leads people here is "Electron version ... is a range, not a fixed + // version", raised when the project has no `node_modules/electron` of its own — a git + // worktree, typically, where module resolution finds the parent checkout's copy but + // electron-builder looks only at the project's. The fix is `npm ci` in the worktree, not + // a second declaration of the version. // Declared rather than left to default BECAUSE the default is package.json's `author` — one // name, where LICENSE has two holders. Feeds Info.plist's NSHumanReadableCopyright and the // Windows LegalCopyright, so leaving it implicit put an attribution on the binary that the diff --git a/package-lock.json b/package-lock.json index 089d62674..364c07429 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,13 +7,13 @@ "": { "name": "openscreen", "version": "1.10.0", + "license": "MIT", "dependencies": { "@fix-webm-duration/fix": "^1.0.1", "@langchain/anthropic": "^1.3.26", "@langchain/core": "^1.1.44", "@langchain/mistralai": "^1.0.8", "@langchain/openai": "^1.4.2", - "@mediapipe/selfie_segmentation": "^0.1.1675465747", "@radix-ui/react-accordion": "^1.2.12", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.16", @@ -67,7 +67,7 @@ "@types/react-dom": "^18.3.7", "@vitejs/plugin-react": "^5.2.0", "autoprefixer": "^10.5.0", - "electron": "^41.2.1", + "electron": "41.2.1", "electron-builder": "^26.15.3", "esbuild": "^0.28.1", "fast-check": "^4.7.0", @@ -2142,12 +2142,6 @@ "node": ">= 10.0.0" } }, - "node_modules/@mediapipe/selfie_segmentation": { - "version": "0.1.1675465747", - "resolved": "https://registry.npmjs.org/@mediapipe/selfie_segmentation/-/selfie_segmentation-0.1.1675465747.tgz", - "integrity": "sha512-IxYxNhwE5VwOm52L1yoFWYLP7q9Pd+NJjzOC5tlepfvEGaY3o9hslhUrx9BgseqdfZtKSDtd/4NfCSMjNzQalA==", - "license": "Apache-2.0" - }, "node_modules/@mistralai/mistralai": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-2.2.1.tgz", diff --git a/package.json b/package.json index 24891039d..8a630d3b5 100644 --- a/package.json +++ b/package.json @@ -154,7 +154,7 @@ "@types/react-dom": "^18.3.7", "@vitejs/plugin-react": "^5.2.0", "autoprefixer": "^10.5.0", - "electron": "^41.2.1", + "electron": "41.2.1", "electron-builder": "^26.15.3", "esbuild": "^0.28.1", "fast-check": "^4.7.0",