Skip to content

Commit f970c91

Browse files
committed
Support setup wizard on PostHog's minimum Node runtime
1 parent 43417ab commit f970c91

12 files changed

Lines changed: 100 additions & 45 deletions

File tree

.github/workflows/release-setup-sourcebot.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ jobs:
112112
docker pull docker.sourcebot.dev/sourcebot-dev/sourcebot:latest
113113
yarn workspace setup-sourcebot test
114114
yarn workspace setup-sourcebot test:e2e
115-
yarn workspace setup-sourcebot test:node22
115+
yarn workspace setup-sourcebot test:node-compatibility
116116
117117
- name: Upgrade npm for Trusted Publishing
118118
working-directory: .

.github/workflows/setup-wizard-e2e.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ jobs:
2121
fail-fast: false
2222
matrix:
2323
os: [ubuntu-latest, macos-latest, windows-latest]
24+
node: ['20.20.0', '22.22.0', '24.x']
2425
runs-on: ${{ matrix.os }}
2526
env:
2627
PACKAGE_TRACKER_ANALYTICS: 'false'
@@ -36,14 +37,19 @@ jobs:
3637
- run: yarn rebuild node-pty
3738
- run: yarn workspace @sourcebot/schemas build
3839
- run: yarn workspace setup-sourcebot build
40+
- name: Select end-user test runtime
41+
uses: actions/setup-node@v4
42+
with:
43+
node-version: ${{ matrix.node }}
44+
- run: corepack enable
3945
- run: yarn workspace setup-sourcebot test
4046
- run: yarn workspace setup-sourcebot test:platform
4147
- name: Linux packed-artifact and runtime checks
42-
if: runner.os == 'Linux'
48+
if: runner.os == 'Linux' && matrix.node == '24.x'
4349
run: |
4450
docker pull docker.sourcebot.dev/sourcebot-dev/sourcebot:latest
4551
yarn workspace setup-sourcebot test:e2e
46-
yarn workspace setup-sourcebot test:node22
52+
yarn workspace setup-sourcebot test:node-compatibility
4753
yarn workspace setup-sourcebot test:baseline
4854
node packages/setupWizard/tests/e2e/packageManagers.mjs
4955

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,6 @@ jobs:
4141
run: yarn install --frozen-lockfile
4242

4343
- name: Test
44-
# The CLI requires Node 24 and is built/tested by setup-wizard-e2e.
44+
# The CLI has separate packed-artifact and Node-compatibility gates in setup-wizard-e2e.
4545
# Keep the application workspaces on their existing runtime here.
4646
run: yarn workspaces foreach --all --topological --exclude setup-sourcebot --exclude 'root-workspace-*' run test

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
## [Unreleased]
99

1010
### Added
11-
- Added privacy-scoped setup wizard funnel telemetry with deployment identity handoff and Node 24 support. [#1653](https://github.com/sourcebot-dev/sourcebot/pull/1653)
11+
- Added privacy-scoped setup wizard funnel telemetry with deployment identity handoff, supporting Node.js from 20.20.0. [#1653](https://github.com/sourcebot-dev/sourcebot/pull/1653)
1212
- Added isolated live setup CLI deployment tests covering public code hosts, local clones, AI configuration, search, and restart identity; repaired cross-platform test-runner cleanup. [#1653](https://github.com/sourcebot-dev/sourcebot/pull/1653)
1313

1414
## [5.1.13] - 2026-09-12

packages/setupWizard/README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ The wizard walks you through:
1717

1818
## Requirements
1919

20-
- Node.js 24+
20+
- Node.js 20.20+ (20.x), 22.22+ (22.x), or 23.5+ (including 24+). Node 24 LTS is recommended; Node 20 is supported for compatibility but is end-of-life.
2121
- Docker and Docker Compose
2222

2323
## Development tests
@@ -29,11 +29,15 @@ yarn workspace @sourcebot/schemas build
2929
yarn workspace setup-sourcebot build
3030
yarn workspace setup-sourcebot test
3131
yarn workspace setup-sourcebot test:e2e
32+
yarn workspace setup-sourcebot test:node-compatibility
3233
```
3334

3435
The E2E tests compile and pack the package, install it outside the repository,
3536
drive its published binary in a PTY, inspect real SDK requests through a local TLS
3637
collector, and clean up temporary installations. OpenSSL and Docker are required.
38+
The compatibility suite tests the same tarball under Node 20.20.0 and 22.22.0,
39+
and checks early rejection on Node 18, 20.19, and 22.21. Build/release tooling
40+
continues to use Node 24; that is not the end-user minimum.
3741
The runtime suite uses `docker.sourcebot.dev/sourcebot-dev/sourcebot:latest`
3842
(override only the test image with `SETUP_TEST_SOURCEBOT_IMAGE`).
3943

packages/setupWizard/bin.cjs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
#!/usr/bin/env node
2-
if (Number(process.versions.node.split('.')[0]) < 24) {
3-
console.error('setup-sourcebot requires Node.js 24 or newer. Please upgrade Node.js.');
2+
// Intersection of posthog-node and @inquirer/prompts runtime requirements.
3+
const [major, minor] = process.versions.node.split('.').map(Number);
4+
const supported = (major === 20 && minor >= 20) ||
5+
(major === 22 && minor >= 22) || (major === 23 && minor >= 5) || major >= 24;
6+
if (!supported) {
7+
console.error('setup-sourcebot requires Node.js 20.20+, 22.22+, or 23.5+ (including Node.js 24+). Please upgrade Node.js.');
48
process.exitCode = 1;
59
} else {
610
import('./dist/index.js').catch(() => {

packages/setupWizard/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"test:platform": "node --test tests/e2e/platform.test.mjs",
2020
"test:linux": "node tests/e2e/linux.mjs",
2121
"test:runtime": "node --test tests/e2e/runtime.test.mjs",
22-
"test:node22": "node tests/e2e/unsupportedNode.mjs",
22+
"test:node-compatibility": "node tests/e2e/nodeCompatibility.mjs",
2323
"test:baseline": "node tests/e2e/baseline.mjs",
2424
"test:live": "node tests/e2e/liveSmoke.mjs"
2525
},
@@ -33,14 +33,14 @@
3333
},
3434
"devDependencies": {
3535
"@sourcebot/schemas": "workspace:^",
36-
"@types/node": "^24.0.0",
36+
"@types/node": "^20.19.43",
3737
"node-pty": "^1.1.0",
3838
"tsx": "^4.21.0",
3939
"typescript": "^5.6.2",
4040
"undici": "^7"
4141
},
4242
"engines": {
43-
"node": ">=24.0.0"
43+
"node": "^20.20.0 || ^22.22.0 || >=23.5.0"
4444
},
4545
"files": [
4646
"dist",

packages/setupWizard/tests/e2e/harness.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export function contract(events, requireTerminal = true) {
4444
assert.equal(event.properties.$lib_version, '5.52.1');
4545
assert.equal(event.properties.$geoip_disable, true);
4646
assert.equal(event.properties.$ignore_sent_at, true);
47-
assert.equal(event.properties.nodeMajorVersion, 24);
47+
assert.equal(event.properties.nodeMajorVersion, Number(process.versions.node.split('.')[0]));
4848
assert.equal(event.properties.source, 'setup-sourcebot-cli');
4949
assert.equal(event.properties.schemaVersion, 1);
5050
assert.ok(event.properties.elapsedMs >= elapsed);
@@ -63,7 +63,7 @@ export function contract(events, requireTerminal = true) {
6363
}
6464

6565
export function artifact() {
66-
assert.equal(Number(process.versions.node.split('.')[0]), 24, 'Run packed-artifact tests using Node 24');
66+
assert.ok(Number(process.versions.node.split('.')[0]) >= 20, 'Run packed-artifact tests on Node 20 or newer');
6767
// node-pty 1.1.0 ships its macOS helper without its executable bit in the npm tarball.
6868
if (process.platform === 'darwin') {
6969
const helper = join(dirname(require.resolve('node-pty/package.json')), 'prebuilds', `darwin-${process.arch}`, 'spawn-helper');
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import assert from 'node:assert/strict';
2+
import { execFileSync, spawnSync } from 'node:child_process';
3+
import { mkdirSync, readdirSync } from 'node:fs';
4+
import { join, dirname, delimiter } from 'node:path';
5+
import { artifact } from './harness.mjs';
6+
7+
// Build once on the release runtime, then install and exercise that exact tarball
8+
// on each minimum supported LTS runtime. No production telemetry is sent.
9+
const packed = artifact();
10+
const packageRoot = new URL('../..', import.meta.url);
11+
try {
12+
for (const version of ['20.20.0', '22.22.0', '18.20.8', '20.19.0', '22.21.0']) {
13+
const runtimeRoot = join(packed.root, `node-${version}`);
14+
mkdirSync(runtimeRoot);
15+
execFileSync('npm', ['install', '--prefix', runtimeRoot, '--no-audit', '--no-fund', '--cache', join(packed.root, 'runtime-cache'), `node@${version}`], { stdio: 'pipe', timeout: 120000 });
16+
const node = join(runtimeRoot, 'node_modules/node/bin/node');
17+
const env = { ...process.env, PATH: `${dirname(node)}${delimiter}${process.env.PATH}`, PACKAGE_TRACKER_ANALYTICS: 'false', SETUP_TEST_TARBALL: packed.tarball };
18+
if (['20.20.0', '22.22.0'].includes(version)) {
19+
const tests = [
20+
...['unit', 'integration'].flatMap(dir => readdirSync(new URL(`../${dir}/`, import.meta.url)).filter(f => f.endsWith('.test.mjs')).map(f => `tests/${dir}/${f}`)),
21+
...['wizard', 'collectors', 'docker', 'safety', 'platform'].map(f => `tests/e2e/${f}.test.mjs`),
22+
];
23+
execFileSync(node, ['--test', '--test-concurrency=1', ...tests], { cwd: packageRoot, env, stdio: 'inherit', timeout: 600000 });
24+
console.log(`Node ${version}: packed CLI and telemetry regression suites passed; artifact ${packed.digest}`);
25+
} else {
26+
const work = join(runtimeRoot, 'empty-home');
27+
mkdirSync(work);
28+
const result = spawnSync(node, [join(packed.installed, 'bin.cjs')], { cwd: work, encoding: 'utf8', env: { PATH: '', HOME: work }, timeout: 10000 });
29+
assert.equal(result.status, 1);
30+
assert.match(result.stderr, /requires Node.js 20\.20\+, 22\.22\+, or 23\.5\+/);
31+
assert.equal(result.stdout, '');
32+
assert.deepEqual(readdirSync(work), []);
33+
console.log(`Node ${version}: rejected before importing the wizard`);
34+
}
35+
}
36+
} finally {
37+
packed.cleanup();
38+
}

packages/setupWizard/tests/e2e/unsupportedNode.mjs

Lines changed: 0 additions & 19 deletions
This file was deleted.

0 commit comments

Comments
 (0)