Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
- name: Set up Node.js 24
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24.x
node-version: 24.22.1
cache: npm
- name: Install locked dependencies
run: npm ci
Expand Down Expand Up @@ -59,15 +59,17 @@ jobs:
run: npm run actionlint

locked:
name: Locked OpenAI / Node.js ${{ matrix.node-version }}
name: Locked OpenAI / Node.js ${{ matrix.node-major }}.x
runs-on: ubuntu-latest
timeout-minutes: 25
strategy:
fail-fast: false
matrix:
node-version:
- 22.x
- 24.x
include:
- node-version: 22.23.4
node-major: "22"
- node-version: 24.22.1
node-major: "24"
steps:
- name: Check out the repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand Down Expand Up @@ -118,7 +120,7 @@ jobs:
- name: Set up Node.js 24
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24.x
node-version: 24.22.1
cache: npm
- name: Install locked dependencies
run: npm ci
Expand Down Expand Up @@ -179,7 +181,7 @@ jobs:
- name: Set up Node.js 22
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 22.x
node-version: 22.23.4
cache: npm
- name: Install locked development dependencies
run: npm ci
Expand All @@ -202,7 +204,7 @@ jobs:
- name: Set up Node.js 24
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24.x
node-version: 24.22.1
cache: npm
- name: Install locked development dependencies
run: npm ci
Expand All @@ -222,7 +224,7 @@ jobs:
- name: Set up Node.js 26
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 26.x
node-version: 26.12.1
cache: npm
- name: Install locked dependencies
run: npm ci
Expand All @@ -249,7 +251,7 @@ jobs:
- name: Set up Node.js 24
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24.x
node-version: 24.22.1
cache: npm
- name: Install locked dependencies
run: npm ci
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/live-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
- name: Set up Node.js 24
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24.x
node-version: 24.22.1
cache: npm
- name: Install locked dependencies
run: npm ci
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ jobs:
- name: Set up Node.js 24
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24.x
node-version: 24.22.1
cache: npm
- name: Classify the exact Release Please handoff
id: result
Expand Down Expand Up @@ -544,7 +544,7 @@ jobs:
- name: Set up Node.js 24
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24.x
node-version: 24.22.1
cache: npm
- name: Install validation dependencies without lifecycle scripts
run: npm ci --ignore-scripts
Expand Down Expand Up @@ -695,7 +695,7 @@ jobs:
- name: Set up Node.js 24
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24.x
node-version: 24.22.1
cache: npm
- name: Install locked dependencies
run: npm ci
Expand Down Expand Up @@ -755,7 +755,7 @@ jobs:
- name: Set up Node.js 24
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24.x
node-version: 24.22.1
package-manager-cache: false
registry-url: https://registry.npmjs.org
- name: Use a Trusted Publishing-capable npm CLI
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ jobs:
- name: Set up Node.js 24
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24.x
node-version: 24.22.1
cache: npm
- name: Install validation dependencies without lifecycle scripts
run: npm ci --ignore-scripts
Expand Down
9 changes: 5 additions & 4 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,11 @@ does not establish GitHub Actions execution.

## Runtime policy

The package `engines` contract supports Node.js 22 and 24 only. Node.js 26 is an
advisory compatibility target and remains outside `engines` until it enters LTS
and the policy is deliberately updated. Node.js 18 and 20 are unsupported. The
normal publication runtime is Node.js 24 and must satisfy npm Trusted
The package `engines` contract supports patched Node.js 22.23.4+ and 24.22.1+
within those major lines only. Node.js 26 is an advisory compatibility target
and remains outside `engines` until it enters LTS and the policy is deliberately
updated. Node.js 18 and 20 are unsupported. The normal publication runtime is
Node.js 24.22.1+ and must satisfy npm Trusted
Publishing's minimum Node.js and npm CLI versions recorded in
[RELEASING.md](./RELEASING.md).

Expand Down
10 changes: 5 additions & 5 deletions COMPATIBILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,11 @@ deferred. No compatibility aliases are provided for legacy client names.
The consumer manifest range is `openai:^6.47.0`. Release documentation may list a
version as verified only after the corresponding lane passes.

| Lane | Version selection | Runtime | Required evidence |
| ----------- | -------------------------------- | ----------------- | ---------------------------------------- |
| Minimum | `6.47.0` | Node.js 22 | Runtime and ESM/CommonJS consumer types |
| Development | Version from `package-lock.json` | Node.js 22 and 24 | Every blocking runtime |
| Canary | Latest compatible 6.x | Node.js 24 | Scheduled and dependency-update workflow |
| Lane | Version selection | Runtime | Required evidence |
| ----------- | -------------------------------- | ----------------------------- | ---------------------------------------- |
| Minimum | `6.47.0` | Node.js 22.23.4+ | Runtime and ESM/CommonJS consumer types |
| Development | Version from `package-lock.json` | Node.js 22.23.4+ and 24.22.1+ | Every blocking runtime |
| Canary | Latest compatible 6.x | Node.js 24.22.1+ | Scheduled and dependency-update workflow |

The compatible manifest range can resolve an upstream minor before it appears
in this verified table. If the canary finds an incompatibility, maintainers
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ incidental 0.1 change. Propose future scope through an issue and roadmap update.

## Development setup

Use Node.js 22 or 24 and install exactly from the lock file:
Use patched Node.js 22.23.4+ or 24.22.1+ and install exactly from the lock file:

```bash
npm ci
Expand Down
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ keys are outside the 0.1 scope.

## Requirements

- Node.js 22 or 24
- Node.js 22.23.4 or newer within the 22.x line, or Node.js 24.22.1 or newer
within the 24.x line
- A CometAPI API key

Node.js 26 is an advisory test target until it enters LTS. Node.js 18 and 20 are
not supported. The package `engines` range includes Node.js 22 and 24 only;
passing the Node.js 26 advisory lane does not create a support claim.
Node.js 26 is an advisory test target until it enters LTS; the advisory lane uses
Node.js 26.12.1 or newer. Node.js 18 and 20 are not supported. The package
`engines` range includes only the patched Node.js 22 and 24 lines; passing the
Node.js 26 advisory lane does not create a support claim.

Create an API key at <https://www.cometapi.com/console/token>. Keep it secret:
do not embed it in source code, browser bundles, logs, or committed environment
Expand Down
8 changes: 4 additions & 4 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -438,10 +438,10 @@ dist-tag. Before authorizing release:
call before marking the alpha released. Enable Release Please only after
the initial manual alpha is complete.

The normal publication runner uses Node.js 22.14.0 or later and npm CLI 11.5.1
or later; Node.js 24 is preferred. npm Trusted Publishing requires the manifest
`repository.url` to match the canonical GitHub repository exactly. Publication
is blocked until that canonical URL is configured.
The normal publication runner uses Node.js 24.22.1 or later and npm CLI 11.5.1
or later; a Node.js 22 runner must use 22.23.4 or later. npm Trusted Publishing
requires the manifest `repository.url` to match the canonical GitHub repository
exactly. Publication is blocked until that canonical URL is configured.

## Conditional first-publication bootstrap

Expand Down
7 changes: 4 additions & 3 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -513,9 +513,10 @@ verification.
## First npm Publication Bootstrap

The normal publication path is npm Trusted Publishing from a GitHub-hosted
runner using Node.js 22.14.0 or later, npm CLI 11.5.1 or later, and a
`repository.url` that exactly matches the GitHub repository. Node.js 24 is the
preferred release runtime.
runner using Node.js 24.22.1 or later, npm CLI 11.5.1 or later, and a
`repository.url` that exactly matches the GitHub repository. A Node.js 22
runner must use 22.23.4 or later; Node.js 24.22.1 is the preferred release
runtime.

Maintainers must first attempt to configure the Trusted Publisher normally. If
npm does not allow configuration before the first package publication, only
Expand Down
2 changes: 1 addition & 1 deletion SUPPORT.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

Support for the 0.1 line is limited to the tested operations and runtimes in
[COMPATIBILITY.md](./COMPATIBILITY.md): Chat Completions, Responses, and Models
on Node.js 22 and 24. Node.js 26 is advisory. Inherited OpenAI methods and
on patched Node.js 22.23.4+ and 24.22.1+. Node.js 26 is advisory. Inherited OpenAI methods and
future provider or CometAPI-specific resources are outside this support
contract.

Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"README.md"
],
"engines": {
"node": "^22.0.0 || ^24.0.0"
"node": "^22.23.4 || ^24.22.1"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -69,6 +69,7 @@
"check:standalone-content": "node scripts/check-standalone-content.mjs",
"check:self-contained": "node scripts/check-self-contained.mjs",
"check:public-preview": "node scripts/check-public-preview.mjs",
"check:runtime": "node scripts/check-node-runtime.mjs",
"actionlint": "node scripts/run-actionlint.mjs",
"verify:offline": "node scripts/verify.mjs --offline",
"verify": "node scripts/verify.mjs",
Expand Down
13 changes: 13 additions & 0 deletions scripts/check-node-runtime.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {
isPatchedNodeVersion,
MINIMUM_PATCHED_NODE_VERSIONS,
} from "./node-version-policy.mjs";

const version = `v${process.versions.node}`;
if (!isPatchedNodeVersion(version)) {
console.error(
`Node.js ${version} is below the patched runtime floor (22 >= ${MINIMUM_PATCHED_NODE_VERSIONS[22]}, 24 >= ${MINIMUM_PATCHED_NODE_VERSIONS[24]}, 26 >= ${MINIMUM_PATCHED_NODE_VERSIONS[26]}).`,
);
process.exit(1);
}
console.log(`Node.js runtime ${version} satisfies the patched security floor.`);
30 changes: 30 additions & 0 deletions scripts/node-version-policy.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const minimums = Object.freeze({
22: Object.freeze([22, 23, 4]),
24: Object.freeze([24, 22, 1]),
26: Object.freeze([26, 12, 1]),
});

export const MINIMUM_PATCHED_NODE_VERSIONS = Object.freeze({
22: "22.23.4",
24: "24.22.1",
26: "26.12.1",
});

export function parseNodeVersion(value) {
const match = /^(?:v)?(\d+)\.(\d+)\.(\d+)$/.exec(value ?? "");
if (!match) return null;
return match.slice(1).map(Number);
}

export function isPatchedNodeVersion(
value,
allowedMajors = Object.keys(minimums),
) {
const parsed = parseNodeVersion(value);
if (!parsed || !allowedMajors.map(Number).includes(parsed[0])) return false;
const minimum = minimums[parsed[0]];
return (
parsed[1] > minimum[1] ||
(parsed[1] === minimum[1] && parsed[2] >= minimum[2])
);
}
28 changes: 22 additions & 6 deletions scripts/release-validation.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const SEMVER_TOKEN_PATTERN = new RegExp(
"gi",
);

export const SUPPORTED_NODE_ENGINES = "^22.0.0 || ^24.0.0";
export const SUPPORTED_NODE_ENGINES = "^22.23.4 || ^24.22.1";
export const SUPPORTED_OPENAI_RANGE = "^6.47.0";

export const CANONICAL_IDENTITY = Object.freeze({
Expand Down Expand Up @@ -154,17 +154,23 @@ function assertSupportedNodeEngines(manifest, label) {
}

const majors = range.split(/\s*\|\|\s*/).map((clause) => {
const match = /^\^(0|[1-9]\d*)\.0\.0$/.exec(clause);
const match = /^\^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/.exec(clause);
if (!match) {
throw new Error(
`${label} engines.node contains an unsupported range: ${clause}.`,
);
}
return Number(match[1]);
return [Number(match[1]), Number(match[2]), Number(match[3])];
});
if (majors.length !== 2 || majors[0] !== 22 || majors[1] !== 24) {
if (
JSON.stringify(majors) !==
JSON.stringify([
[22, 23, 4],
[24, 22, 1],
])
) {
throw new Error(
`${label} engines.node must support exactly Node.js 22 and 24.`,
`${label} engines.node must support patched Node.js 22.23.4 and 24.22.1 ranges.`,
);
}
}
Expand Down Expand Up @@ -387,9 +393,19 @@ export function validatePublicationNeutralReadme(readme) {
"README.md must link to the unversioned cometapi npm package page.",
);
}
const readmeVersionText = [
document.referenceText,
...markdownCodeValues(document.root),
]
.join("\n")
// Runtime patch floors are durable compatibility policy, not package
// release pins. Keep allowing the explicit Node.js versions required by
// the supported runtime matrix while rejecting package and dependency
// versions elsewhere in the README.
.replace(/\bNode(?:\.js)?\s+\d+\.\d+\.\d+/gi, "Node.js runtime");
if (
new RegExp(SEMVER_TOKEN_PATTERN.source, SEMVER_TOKEN_PATTERN.flags).test(
[document.referenceText, ...markdownCodeValues(document.root)].join("\n"),
readmeVersionText,
)
) {
throw new Error(
Expand Down
2 changes: 1 addition & 1 deletion scripts/release-workflow-validation.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const RELEASE_WORKFLOW_STEP = "Run Release Please";
const PUBLISH_OPERATION = "release";
const NPM_TAG_POLICY_ID = 55718965;
const PUBLISH_WORKFLOW_CONTRACT_SHA256 =
"684e15c13835ae3b139929ae78e5bbd5ba618ea8f30ebba8dbb4c42004d57a06";
"379ba8678416ff96d3bcf220a23e8602d2b55890164b2847331def10b4e99693";
const PUBLISH_HANDOFF_IF =
"vars.RELEASE_PLEASE_ENABLED == 'true' && github.event_name == 'workflow_run' && github.run_attempt == 1 && github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push' && github.event.workflow_run.head_branch == 'main'";
const PUBLISH_RESULT_IF = "steps.result.outputs.has-result == 'true'";
Expand Down
1 change: 1 addition & 0 deletions scripts/verify.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { run } from "./lib.mjs";

const offlineOnly = process.argv.includes("--offline");
run("npm", ["run", "check:runtime"]);
const offlineChecks = [
"format:check",
"lint",
Expand Down
7 changes: 5 additions & 2 deletions tests/ci-workflow.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,11 @@ describe("blocking CI workflow", () => {
"fail-fast",
"matrix",
]);
expect(Object.keys(locked.strategy.matrix)).toEqual(["node-version"]);
expect(locked.strategy?.matrix?.["node-version"]).toEqual(["22.x", "24.x"]);
expect(Object.keys(locked.strategy.matrix)).toEqual(["include"]);
expect(locked.strategy?.matrix?.include).toEqual([
{ "node-version": "22.23.4", "node-major": "22" },
{ "node-version": "24.22.1", "node-major": "24" },
]);

const liveContractSteps = locked.steps.filter(
(step) => step.run === "npm run test:live-contract",
Expand Down
Loading
Loading