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
2 changes: 1 addition & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ updates:
# change only pnpm-lock.yaml.
versioning-strategy: 'increase-if-necessary'
ignore:
# @types/node tracks the oldest supported Node (`engines.node` >=20).
# @types/node tracks the oldest supported Node (`engines.node` >=22).
- dependency-name: '@types/node'
update-types:
- 'version-update:semver-major'
Expand Down
47 changes: 5 additions & 42 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -150,54 +150,17 @@ jobs:
stryker.log
if-no-files-found: ignore

sdk-node20:
name: SDK Node 20 lint, tests, and build
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
with:
persist-credentials: false

- name: Set up pnpm
uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
with:
version: 10.34.1

- name: Set up Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6
with:
node-version: '20.20.2'
cache: 'pnpm'

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Run SDK quality checks
run: pnpm quality:checks

- name: Preserve failing tests and property counterexamples
if: ${{ failure() }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: test-failures-node-20
path: reports/unit.json
if-no-files-found: ignore

sdk-required:
name: SDK Lint, Tests, and Build
if: ${{ always() }}
needs: [sdk, sdk-node20]
needs: [sdk]
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Require both runtime checks and every mutation shard
- name: Require every mutation shard
env:
RESULTS: ${{ toJSON(needs.*.result) }}
run: jq -e 'length == 2 and all(. == "success")' <<< "$RESULTS"
run: jq -e 'length == 1 and all(. == "success")' <<< "$RESULTS"

mutation-inventory:
name: Mutation shard inventory
Expand Down Expand Up @@ -231,11 +194,11 @@ jobs:
quality:
name: Quality Gate
if: ${{ always() }}
needs: [policy, actions, sdk, sdk-node20, sdk-required, mutation-inventory]
needs: [policy, actions, sdk, sdk-required, mutation-inventory]
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Require every mandatory job to succeed
env:
RESULTS: ${{ toJSON(needs.*.result) }}
run: jq -e 'length == 6 and all(. == "success")' <<< "$RESULTS"
run: jq -e 'length == 5 and all(. == "success")' <<< "$RESULTS"
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Thanks for your interest in improving the Volcano JavaScript SDK.

## Local Prerequisites

- Node.js 22.23.3 from `.node-version` for development. The package supports Node.js 20 or newer.
- Node.js 22.23.3 from `.node-version` for development. The package supports Node.js 22 or newer.
- pnpm 10.34.1.

## Common Workflows
Expand All @@ -29,7 +29,7 @@ platform implementation.
[Are the Types Wrong](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/packages/cli/README.md)
against the same tarball. ATTW's native `node16` profile checks CommonJS, ESM,
and bundler resolution through the package export map. Legacy Node 10 resolution
is outside the SDK's Node 20+ support; no diagnostic rules or entrypoints are ignored.
is outside the SDK's Node 22+ support; no diagnostic rules or entrypoints are ignored.
`pnpm test:quickstart` also installs that tarball in an isolated consumer and
checks realtime imports and the documented quickstart.

Expand Down
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,8 @@ The SDK declares it as an optional peer dependency, which is what lets the SDK
resolve it in the deployed function without anything else installing it: a
browser bundle and a standard function stay as small as they were. Its install
closure is ~19 MB, which is why it belongs in durable functions rather than in
everyone's `node_modules`. It also requires Node 22, where this SDK supports
Node 20, so it is only ever installed on the runtimes that can host a durable
function (`nodejs22.x` and `nodejs24.x`).
everyone's `node_modules`. It is only ever installed on the runtimes that can
host a durable function (`nodejs22.x` and `nodejs24.x`).

A function that declares it explicitly is left alone by the build, version
included, which is the way to pin a specific runtime.
Expand Down
3 changes: 1 addition & 2 deletions __tests__/durable-runtime-packaging.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import { describe, expect, test } from '@jest/globals';

// Installing this SDK must never install the durable runtime. Volcano puts it in
// a durable function's own dependencies when it builds one, on a Node runtime
// that satisfies the runtime's own `engines` — nowhere else does it belong, and
// this repo supports Node 20, which the runtime does not.
// that satisfies the runtime's own `engines` — nowhere else does it belong.
//
// It is declared as an optional peer so the SDK can still resolve it from inside
// a strict node_modules layout once the build has added it to the function.
Expand Down
2 changes: 1 addition & 1 deletion docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: 'This guide walks you through installing the Volcano SDK and making
---

Install the SDK, sign in, and read a server-validated user profile.
Use Node.js 20 or later for the runnable quickstart below. `VolcanoClient` is the
Use Node.js 22 or later for the runnable quickstart below. `VolcanoClient` is the
client for new applications; `VolcanoAuth` remains a compatible alias.

## Installation
Expand Down
2 changes: 1 addition & 1 deletion docs/versions.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Commit `package.json` and `package-lock.json`. Use `npm ci` to reproduce that de

## Runtime and compatibility

Use Node.js 20 or later, or a browser with the APIs required by the feature you use. The native CI suite runs on Node.js 20; publishing builds run on Node.js 24. Durable function authoring needs its separately documented runtime.
Use Node.js 22 or later, or a browser with the APIs required by the feature you use. The native CI suite runs on Node.js 22; publishing builds run on Node.js 24. Durable function authoring needs its separately documented runtime.

The package uses semantic versions. Read the migration notes before a major update and the release notes before any update.
JavaScript, Python and Ruby releases have independent version numbers; matching numbers are not a compatibility requirement.
Expand Down
2 changes: 1 addition & 1 deletion examples/nextjs-notes-app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ A full-featured notes application demonstrating the **Volcano SDK** capabilities

### 1. Prerequisites

- Node.js 20.9+ (required by Next.js 16)
- Node.js 22+ (required by `@volcano.dev/sdk`)
- A Volcano project
- A database with the `notes` table (see schema below)

Expand Down
7 changes: 2 additions & 5 deletions maintainers/mutation-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,8 @@
`pnpm quality` runs Stryker against every handwritten runtime file under `src/`.
Generated files, declarations, and tests are outside the mutation target. A
local run checks the complete target; CI runs the same command in 32 required
shards on Node 22. Node 20 runs the full nonmutation quality checks and tests.
In [Node 20's full mutation run](https://github.com/Kong/volcano-sdk-js/actions/runs/35990154684/job/107602058701),
four malformed part-bound mutants abort the native `Blob.slice` implementation
with `SIGABRT` (`node::Blob::ToSlice`); the [same shard on Node 22](https://github.com/Kong/volcano-sdk-js/actions/runs/35990154684/job/107602058808)
kills all mutants. The Node 20 crash is not a useful mutant detection.
shards on Node 22, and each shard first runs the full nonmutation quality checks
and tests.
`scripts/verify-mutation-shards.mts` compares the shard mutant counts with
Stryker's unfiltered inventory, so a missing range or empty shard fails the
gate.
Expand Down
22 changes: 11 additions & 11 deletions maintainers/quality-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ Codex review and repository merge protection remain separate controls.
## Toolchain pins

[setup-node](https://github.com/actions/setup-node) reads `.node-version` for
Node 22 development and quality jobs. The compatibility job pins Node 20
separately; the package's `engines` range remains `>=20`. Release jobs retain
Node 24 and pin npm 11. Go is only used to run actionlint. Update these exact
patch versions from the [Node release index](https://nodejs.org/dist/index.json),
Node 22 development and quality jobs; the package's `engines` range is `>=22`,
and CI tests that pinned Node 22 patch. Release jobs retain Node 24 and pin
npm 11. Go is only used to run actionlint. Update these exact patch versions
from the [Node release index](https://nodejs.org/dist/index.json),
[npm registry](https://registry.npmjs.org/npm), and
[Go release history](https://go.dev/doc/devel/release), then rerun quality.

Expand All @@ -52,25 +52,25 @@ script and native Node test. `pnpm build:tooling` emits ordinary JavaScript into
source entrypoints, and the tracked-file policy rejects untyped scripts or tests.
Jest's two CJS loader files only load the compiled environment adapters.

Use the existing compiler and [Node test runner](https://nodejs.org/docs/latest-v20.x/api/test.html):
Use the existing compiler and [Node test runner](https://nodejs.org/docs/latest-v22.x/api/test.html):
[TypeScript rewrites relative extensions](https://www.typescriptlang.org/tsconfig/rewriteRelativeImportExtensions.html)
from `.mts`/`.cts` to `.mjs`/`.cjs`. Keeping the compiler output beside `scripts/`
preserves root-relative asset paths. Standalone package, test, and mutation tasks
build their prerequisites; CI compiles and invokes the policy test independently
of the task graph it checks. The npm package's explicit file list excludes tooling.

[Node's built-in type stripping](https://nodejs.org/api/typescript.html) cannot
serve the retained Node 20 lane and does not type-check. [tsx](https://tsx.hirok.io/typescript)
would still require a separate type check and an additional runtime loader.
[Node's built-in type stripping](https://nodejs.org/api/typescript.html) is off
by default before Node 22.18, which `engines` still allows, and does not
type-check. [tsx](https://tsx.hirok.io/typescript) would still require a separate type check and an additional runtime loader.
Compiler emission keeps execution on the same ordinary Node module system used
by consumers. No type assertions or typing suppressions are needed at the
JSON report, child-process, HTTP, or test-runner boundaries.

The [native reporter API](https://nodejs.org/docs/latest-v20.x/api/test.html#custom-reporters)
supplies execution events, but Node 20/22 have no fail-on-skip or fail-on-empty
The [native reporter API](https://nodejs.org/docs/latest-v22.x/api/test.html#custom-reporters)
supplies execution events, but Node 22 has no fail-on-skip or fail-on-empty
switch. Node even reports an empty test file as a passing case named after its
path; Node 22 accepts an unmatched test glob. `scripts/node-completeness.mts`
rejects those outcomes and skipped or pending cases while the native TAP reporter
formats results. Negative suites prove these failures on both runtime versions.
formats results. Negative suites prove these failures.
ESLint rejects empty test files, focus and skip syntax before execution, including
native test options.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
}
},
"engines": {
"node": ">=20"
"node": ">=22"
},
"files": [
"dist",
Expand Down Expand Up @@ -147,7 +147,7 @@
"@stryker-mutator/jest-runner": "9.6.1",
"@types/babel__core": "7.20.5",
"@types/jest": "30.0.0",
"@types/node": "20.19.43",
"@types/node": "22.20.5",
"@types/ws": "8.18.2",
"@typescript-eslint/eslint-plugin": "^8.58.0",
"@typescript-eslint/parser": "^8.58.0",
Expand Down
Loading