Skip to content

Commit 610c697

Browse files
authored
build: restore libc discriminator on linux lockfile entries (#1163)
* build: restore libc discriminator on linux lockfile entries npm 11 silently strips the `libc` field from @optave/codegraph-linux-* entries in package-lock.json on `npm install`, even though the published packages declare it correctly. Without the discriminator, npm cannot tell linux-x64-gnu apart from linux-x64-musl when resolving the lockfile, so the wrong native binary may load on Alpine/musl hosts. Restore the field and add a CI guard (run before `npm install` in the lint job) that fails any PR which lands a lockfile missing the discriminator — Dependabot bumps and contributor installs would otherwise silently regress this again. Closes #1160 * fix: resolve lockfile path relative to script location (#1163) Use import.meta.url to find package-lock.json regardless of the process CWD. Previously running 'node scripts/verify-lockfile-libc.mjs' from the scripts/ subdirectory failed with a confusing ENOENT instead of running the actual check.
1 parent a029d43 commit 610c697

3 files changed

Lines changed: 70 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ jobs:
2121
with:
2222
node-version: 22
2323

24+
# Runs before `npm install` because npm 11 silently strips the `libc`
25+
# field from optional-dependency lockfile entries (see #1160). If the
26+
# check ran post-install we'd flag every CI run instead of the PRs that
27+
# actually introduce the regression.
28+
- name: Verify lockfile libc discriminators
29+
run: node scripts/verify-lockfile-libc.mjs
30+
2431
- name: Install dependencies
2532
timeout-minutes: 20
2633
shell: bash

package-lock.json

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/verify-lockfile-libc.mjs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/env node
2+
// Verifies that @optave/codegraph-linux-* entries in package-lock.json declare
3+
// the `libc` discriminator. npm 11 silently strips this field when generating
4+
// the lockfile on non-Linux hosts (and sometimes on Linux too), even though the
5+
// published packages declare it. Without it, npm cannot disambiguate
6+
// linux-x64-gnu vs linux-x64-musl when resolving from the lockfile and may
7+
// install (or load) the wrong native binary on Alpine/musl hosts.
8+
//
9+
// Run via `npm run lint` (or directly) in CI to catch silent regressions from
10+
// Dependabot bumps and contributor `npm install` runs.
11+
import { readFileSync } from 'node:fs';
12+
import { dirname, resolve } from 'node:path';
13+
import { fileURLToPath } from 'node:url';
14+
15+
const EXPECTED_LIBC = {
16+
'@optave/codegraph-linux-arm64-gnu': 'glibc',
17+
'@optave/codegraph-linux-x64-gnu': 'glibc',
18+
'@optave/codegraph-linux-x64-musl': 'musl',
19+
};
20+
21+
// Resolve relative to this script's location so it works regardless of CWD
22+
// (e.g. running `node scripts/verify-lockfile-libc.mjs` from the `scripts/`
23+
// subdirectory still finds the repo-root lockfile).
24+
const __dirname = dirname(fileURLToPath(import.meta.url));
25+
const lockfilePath = resolve(__dirname, '..', 'package-lock.json');
26+
const lock = JSON.parse(readFileSync(lockfilePath, 'utf8'));
27+
const failures = [];
28+
29+
for (const [pkgName, expectedLibc] of Object.entries(EXPECTED_LIBC)) {
30+
const entry = lock.packages?.[`node_modules/${pkgName}`];
31+
if (!entry) {
32+
failures.push(`${pkgName}: missing from package-lock.json`);
33+
continue;
34+
}
35+
const libc = entry.libc;
36+
if (!Array.isArray(libc) || !libc.includes(expectedLibc)) {
37+
failures.push(
38+
`${pkgName}: expected libc=["${expectedLibc}"], got ${JSON.stringify(libc)}`,
39+
);
40+
}
41+
}
42+
43+
if (failures.length > 0) {
44+
console.error('package-lock.json libc discriminator check failed:\n');
45+
for (const f of failures) console.error(` - ${f}`);
46+
console.error(
47+
'\nnpm install may have stripped the libc field. Restore it by editing\n' +
48+
'package-lock.json so each @optave/codegraph-linux-* entry includes\n' +
49+
'its libc field (see expected values above). Tracked in #1160.',
50+
);
51+
process.exit(1);
52+
}
53+
54+
console.log('package-lock.json libc discriminators OK');

0 commit comments

Comments
 (0)