Skip to content

Commit 3e863a7

Browse files
fix: harden npm package lifecycle and Node support (#104)
* fix: harden npm package lifecycle and Node support * fix: make npm package lifecycle package-manager agnostic * fix: test every supported minimum Node.js version * fix: preserve required Node CI status checks
1 parent dd74cdb commit 3e863a7

6 files changed

Lines changed: 80 additions & 9 deletions

File tree

.github/workflows/node-ci.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,21 @@ concurrency:
1414

1515
jobs:
1616
test:
17-
name: ${{ matrix.os }} / node-${{ matrix.node }}
17+
name: ${{ matrix.os }} / node-${{ matrix.node == '22.13.0' && '22' || matrix.node }}
1818
runs-on: ${{ matrix.os }}
1919
timeout-minutes: 20
2020
strategy:
2121
fail-fast: false
2222
matrix:
2323
os: [ubuntu-latest, macos-latest, windows-latest]
24-
node: ["22"]
24+
node: ["22.13.0"]
2525
include:
26+
- os: ubuntu-latest
27+
node: "24.0.0"
2628
- os: ubuntu-latest
2729
node: "24"
30+
- os: ubuntu-latest
31+
node: "26.0.0"
2832
- os: ubuntu-latest
2933
node: "26"
3034

@@ -56,6 +60,10 @@ jobs:
5660
- name: Install dependencies
5761
run: pnpm --dir sdk/typescript install --frozen-lockfile
5862

63+
- name: Audit production dependencies
64+
if: matrix.os == 'ubuntu-latest' && matrix.node == '22.13.0'
65+
run: pnpm --dir sdk/typescript run audit:prod
66+
5967
- name: Typecheck
6068
run: pnpm --dir sdk/typescript run types
6169

.github/workflows/node-release.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ jobs:
9898
- name: Install dependencies
9999
run: sfw pnpm --dir sdk/typescript install --frozen-lockfile
100100

101+
- name: Audit production dependencies
102+
run: sfw pnpm --dir sdk/typescript run audit:prod
103+
101104
- name: Verify
102105
run: |
103106
pnpm --dir sdk/typescript run types

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
99
## Quick start
1010

11-
Requires Node.js 22 or later, Python 3.10 or later, and access to Codex Security.
11+
Requires Node.js 22.13.0 or later in the 22.x release line, Node.js 24.x, or
12+
Node.js 26.x; Python 3.10 or later; and access to Codex Security.
1213

1314
```bash
1415
npm install @openai/codex-security

sdk/typescript/README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ npm install @openai/codex-security
1515
npx @openai/codex-security --version
1616
```
1717

18-
The package supports macOS, Linux, and Windows and requires Node.js 22 or
19-
later. Scanning and exporting findings also require Python 3.10 or later. If
20-
you use Python 3.10, install the `tomli` package. Select another interpreter
21-
with `--python`, `pythonPath`, or `PYTHON` when needed.
18+
The package supports macOS, Linux, and Windows and requires Node.js 22.13.0 or
19+
later in the 22.x release line, Node.js 24.x, or Node.js 26.x. Scanning and
20+
exporting findings also require Python 3.10 or later. If you use Python 3.10,
21+
install the `tomli` package. Select another interpreter with `--python`,
22+
`pythonPath`, or `PYTHON` when needed.
2223

2324
When a newer version is available, the CLI shows the update command for your
2425
installation method. Set `CODEX_SECURITY_NO_UPDATE_NOTICE=1` to hide the

sdk/typescript/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"bugs": "https://github.com/openai/codex-security/issues",
1414
"type": "module",
1515
"engines": {
16-
"node": ">=22"
16+
"node": "^22.13.0 || ^24.0.0 || ^26.0.0"
1717
},
1818
"packageManager": "pnpm@11.9.0+sha512.bd682d5d03fe525ef7c9fd6780c6884d1e756ac4c9c9fe00c538782824310dcf90e3ddc4f53835f06dfaebd5085e41855e0bcbb3b60de2ac5bbab89e5036f03b",
1919
"main": "./dist/index.js",
@@ -39,13 +39,15 @@
3939
"access": "public"
4040
},
4141
"scripts": {
42+
"audit:prod": "pnpm audit --prod --audit-level high",
4243
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
43-
"build": "pnpm run clean && tsc -p tsconfig.build.json",
44+
"build": "node --run clean && tsc -p tsconfig.build.json",
4445
"check:package": "node scripts/check-package.mjs",
4546
"format": "prettier --check --ignore-path .gitignore --ignore-path .prettierignore \"**/*.{cjs,mjs,js,ts,json,md}\"",
4647
"generate:models": "node scripts/generate-models.cjs",
4748
"generate:models:check": "node scripts/generate-models.cjs --check",
4849
"lint": "tsc --noEmit",
50+
"prepack": "node --run build",
4951
"test": "bun test --timeout 30000 ./tests-ts",
5052
"test:package": "node scripts/smoke-package.mjs",
5153
"types": "pnpm run generate:models:check && tsc --noEmit"

sdk/typescript/tests-ts/skeleton.test.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,62 @@ function capture(): {
2828
}
2929

3030
describe("TypeScript package skeleton", () => {
31+
test("advertises the tested Node.js 22, 24, and 26 release lines", async () => {
32+
const packageJson = JSON.parse(
33+
await readFile(new URL("../package.json", import.meta.url), "utf8"),
34+
);
35+
36+
const supportedReleases = ["22.13.0", "22.14.0", "24.0.0", "26.0.0"];
37+
const unsupportedReleases = [
38+
"22.12.0",
39+
"23.0.0",
40+
"23.4.0",
41+
"23.5.0",
42+
"25.0.0",
43+
"27.0.0",
44+
];
45+
46+
expect(
47+
supportedReleases.filter((version) =>
48+
Bun.semver.satisfies(version, packageJson.engines.node),
49+
),
50+
).toEqual(supportedReleases);
51+
expect(
52+
unsupportedReleases.filter((version) =>
53+
Bun.semver.satisfies(version, packageJson.engines.node),
54+
),
55+
).toEqual([]);
56+
});
57+
58+
test("pins each Node.js minimum and preserves protected and latest LTS checks", async () => {
59+
const ciWorkflow = await readFile(
60+
new URL("../../../.github/workflows/node-ci.yml", import.meta.url),
61+
"utf8",
62+
);
63+
64+
expect(ciWorkflow).toContain(
65+
"${{ matrix.node == '22.13.0' && '22' || matrix.node }}",
66+
);
67+
expect(ciWorkflow).toContain('node: ["22.13.0"]');
68+
for (const version of ["24.0.0", "24", "26.0.0", "26"]) {
69+
expect(ciWorkflow).toContain(`node: "${version}"`);
70+
}
71+
});
72+
73+
test("builds packages without a preinstalled package manager and provides a production audit", async () => {
74+
const packageJson = JSON.parse(
75+
await readFile(new URL("../package.json", import.meta.url), "utf8"),
76+
);
77+
78+
expect(packageJson.scripts.build).toBe(
79+
"node --run clean && tsc -p tsconfig.build.json",
80+
);
81+
expect(packageJson.scripts.prepack).toBe("node --run build");
82+
expect(packageJson.scripts["audit:prod"]).toBe(
83+
"pnpm audit --prod --audit-level high",
84+
);
85+
});
86+
3187
test("exposes canonical finding and hardening fields with public types", () => {
3288
const finding = {} as Finding;
3389
const scan = {} as ScanRecord;

0 commit comments

Comments
 (0)