Skip to content

fix(ci): force node-gyp >=12.4.0 so the windows-latest install succeeds - #834

Open
AmaadMartin wants to merge 1 commit into
google:mainfrom
AmaadMartin:upstream-port/ci-node-gyp-vs2026-override
Open

fix(ci): force node-gyp >=12.4.0 so the windows-latest install succeeds#834
AmaadMartin wants to merge 1 commit into
google:mainfrom
AmaadMartin:upstream-port/ci-node-gyp-vs2026-override

Conversation

@AmaadMartin

Copy link
Copy Markdown
Collaborator

Please ensure you have read the contribution guide before creating a pull request.

Link to Issue or Description of Change

1. Link to an existing issue (if applicable):

2. Or, if no issue exists, describe the change:

Problem:

sqlite3@5.1.7 installs via prebuild-install -r napi || node-gyp rebuild. When prebuild-install cannot fetch a prebuilt binary, the fallback source build runs the hoisted node-gyp@8.4.1 that sqlite3 pulls in as an optional dependency. That node-gyp maps only Visual Studio majors 15, 16 and 17, so it rejects the Visual Studio major 18 install now present on the windows-latest runner, and Install dependencies fails before anything is built:

gyp ERR! find VS unknown version "undefined" found at
  "C:\Program Files\Microsoft Visual Studio\18\Enterprise"
gyp ERR! find VS could not find a version of Visual Studio 2017 or newer to use
gyp ERR! node-gyp -v v8.4.1

Because the matrix is fail-fast, the Windows install failure also cancels the macOS and Ubuntu legs, so the whole run reads as red.

Root cause, read from the two packages themselves:

Package Visual Studio mapping
node-gyp@8.4.1 find-visualstudio.js:253,257,261 handle majors 15, 16 and 17 only. Major 18 falls through and versionYear stays undefined.
node-gyp@12.4.0 find-visualstudio.js:392 maps major 18 to 2026; :463 selects toolset v145.

Accuracy note on the premise. The Windows lane is not red on every PR. It fails only when prebuild-install cannot fetch a prebuilt binary and the source build actually starts — one run hit No prebuilt binaries found (target=6 runtime=napi arch=x64 libc= platform=win32) and failed as above, while a run a day later downloaded the prebuilt binary, never invoked node-gyp, and passed. So this is an intermittently-triggered but deterministic failure of the fallback path, not a flake in the usual sense. This change makes that fallback path work instead of being a guaranteed failure.

Solution:

Add a root overrides entry forcing node-gyp to ^12.4.0:

"overrides": {
  "node-gyp": "^12.4.0"
}

12.4.0 is the lowest floor that both recognises Visual Studio major 18 and keeps the engines range (^20.17.0 || >=22.9.0) satisfied by the runner Node.

An override rather than a dependency bump, because every @mikro-orm/sqlite@6.x release exact-pins sqlite3: 5.1.7. Overriding node-gyp itself also means the fix is not specific to one native module: it applies equally to better-sqlite3, which is what #819 switches to.

sqlite3 stays at 5.1.7 and no @mikro-orm version moves — verified package-by-package against the lockfile, see below.

Why the diff shows −553 lines. The deletion count is the point of interest for a reviewer, so to be explicit: it is entirely the node-gyp@8 dependency tree falling out of the lockfile. Nothing is removed from the project's own dependencies. Full delta, computed by comparing the two lockfiles entry by entry:

  • 3 changed: node-gyp 8.4.1 → 12.4.0, nopt 5.0.0 → 9.0.0, abbrev 1.1.1 → 4.0.0
  • 12 added: node-gyp 12's own tree — @isaacs/fs-minipass, exponential-backoff, proc-log, undici@6.28.0, and nested tar/minizlib/minipass/chownr/yallist/which/isexe
  • 42 removed: the node-gyp 8 tree — the cacache@15 / ssri@8 / make-fetch-happen@9 chain, npmlog/gauge/are-we-there-yet, @gar/promisify, @tootallnate/once, socks-proxy-agent@6, and their transitives
  • 16 flag reclassifications: packages such as agent-base and https-proxy-agent move from devOptional to dev, because their only optional consumer (the node-gyp 8 tree) is gone. Purely npm bookkeeping, no version movement.

Dropping the @tootallnate/once and cacache@15 / ssri@8 chain is a side effect of the override, not a goal of this change.

Why 15 of the new lockfile entries carry no license field. They match exactly what npm writes: npm install requests the abbreviated packument, which omits license. main already carries entries without it, including undici, which is one of these.

Alternatives rejected.

  • Set npm_config_msvs_version in the workflow. node-gyp 8.4.1 fails to derive a versionYear at all, so there is no value to match against.
  • Install the VS 2022 build tools on the runner. Adds a multi-gigabyte download to every Windows run, forever.
  • Bump @mikro-orm/sqlite. Every v6 release exact-pins sqlite3: 5.1.7.
  • Wait for fix(deps): upgrade the @mikro-orm family from v6 to v7 #819, which swaps in better-sqlite3. That PR is blocked by this exact install failure, so it cannot be the fix for it.

Testing Plan

Unit Tests:

  • I have added or updated unit tests for my change. — No new test. This change adds no executable product code, and there is no precedent in this repo for a test asserting a lockfile version. The regression signal is the Windows matrix leg itself.
  • All unit tests pass locally.

The two suites that load the native sqlite3 binding, run against a clean npm ci install from this lockfile (confirmed node-gyp@12.4.0, sqlite3@5.1.7 resolved in node_modules):

$ npx vitest run --project unit:core \
    core/test/sessions/database_session_service_test.ts \
    core/test/sessions/db/operations_test.ts

 ✓ |unit:core| core/test/sessions/db/operations_test.ts (15 tests) 162ms
 ✓ |unit:core| core/test/sessions/database_session_service_test.ts (26 tests) 1071ms

 Test Files  2 passed (2)
      Tests  41 passed (41)

npm run build across all workspaces also completes clean on this install.

Manual End-to-End (E2E) Tests:

Lockfile integrity was verified independently rather than taken on trust:

  1. Starting from main's package.json and package-lock.json, injected only the overrides block and let npm resolve it against https://registry.npmjs.org/. The result is byte-identical to the lockfile committed here — so this is reproducible npm output, contains no hand edits, and a contributor running npm install will see no churn.
  2. npm ci resolves the committed lockfile cleanly (1140 packages), confirming package.json and package-lock.json agree.
  3. Every resolved URL in the lockfile points at registry.npmjs.org (1137 of 1137).

Checklist

  • I have read the CONTRIBUTING.md document.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas. — n/a, no code.
  • I have added tests that prove my fix is effective or that my feature works. — see the note above; the Windows matrix leg is the signal.
  • New and existing unit tests pass locally with my changes.
  • I have manually tested my changes end-to-end.
  • Any dependent changes have been merged and published in downstream modules.

Additional context

If another change adding a root overrides block lands around the same time, please merge the two blocks rather than replace one with the other.

`sqlite3@5.1.7` installs via `prebuild-install -r napi || node-gyp rebuild`.
When no prebuilt binary is available for the runner, the fallback source build
runs the hoisted `node-gyp@8.4.1` that `sqlite3` pulls in as an optional
dependency. That node-gyp maps only Visual Studio majors 15, 16 and 17, so it
rejects the Visual Studio major 18 install present on `windows-latest` and the
Install dependencies step fails before anything is built:

    gyp ERR! find VS unknown version "undefined" found at
      "C:\Program Files\Microsoft Visual Studio\18\Enterprise"
    gyp ERR! find VS could not find a version of Visual Studio 2017 or newer to use
    gyp ERR! node-gyp -v v8.4.1

Add a root `overrides` entry forcing `node-gyp` to `^12.4.0`. 12.4.0 is the
lowest floor that both recognises Visual Studio major 18 (mapping it to 2026 and
selecting toolset v145) and keeps the `engines` range satisfied by the runner
Node. An override rather than a dependency bump because every
`@mikro-orm/sqlite@6.x` release exact-pins `sqlite3: 5.1.7`.

`sqlite3` stays at `5.1.7` and no `@mikro-orm` version moves.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant