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
16 changes: 13 additions & 3 deletions .github/workflows/release-setup-sourcebot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20.x'
node-version: '24.x'

- name: Install dependencies
working-directory: .
Expand Down Expand Up @@ -103,11 +103,21 @@ jobs:
# publishing.
yarn pack --out /tmp/setup-sourcebot.tgz

- name: Verify the exact publish artifact

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This release-gating step runs the full e2e suite (booting 8+ real Sourcebot Docker containers in runtime.test.mjs) plus test:node-compatibility, which downloads Node 18.20.8/20.19.0/20.20.0/22.21.0/22.22.0 runtimes over npm and re-runs the whole unit/integration/e2e suite on two of them. Neither the step nor the job sets timeout-minutes, so a slow registry, long image pull, or hung container holds the step at the 360-minute default; with cancel-in-progress: false a stuck run also blocks subsequent releases in the group. The repo already caps the identical suite at 20 minutes in setup-wizard-e2e.yml (timeout-minutes: 20). Add a sensible timeout-minutes to this step or job.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/release-setup-sourcebot.yml, line 106:

<comment>This release-gating step runs the full e2e suite (booting 8+ real Sourcebot Docker containers in runtime.test.mjs) plus test:node-compatibility, which downloads Node 18.20.8/20.19.0/20.20.0/22.21.0/22.22.0 runtimes over npm and re-runs the whole unit/integration/e2e suite on two of them. Neither the step nor the job sets timeout-minutes, so a slow registry, long image pull, or hung container holds the step at the 360-minute default; with `cancel-in-progress: false` a stuck run also blocks subsequent releases in the group. The repo already caps the identical suite at 20 minutes in setup-wizard-e2e.yml (timeout-minutes: 20). Add a sensible timeout-minutes to this step or job.</comment>

<file context>
@@ -103,11 +103,21 @@ jobs:
           # publishing.
           yarn pack --out /tmp/setup-sourcebot.tgz
 
+      - name: Verify the exact publish artifact
+        working-directory: .
+        env:
</file context>
Suggested change
- name: Verify the exact publish artifact
- name: Verify the exact publish artifact
timeout-minutes: 30

working-directory: .
env:
PACKAGE_TRACKER_ANALYTICS: 'false'
SETUP_TEST_TARBALL: /tmp/setup-sourcebot.tgz
run: |
docker pull docker.sourcebot.dev/sourcebot-dev/sourcebot:latest
yarn workspace setup-sourcebot test
yarn workspace setup-sourcebot test:e2e
yarn workspace setup-sourcebot test:node-compatibility

- name: Upgrade npm for Trusted Publishing
working-directory: .
run: |
# OIDC Trusted Publishing requires npm >= 11.5.1; Node 20 ships an
# older npm.
# OIDC Trusted Publishing requires npm >= 11.5.1.
npm install -g npm@latest
npm --version

Expand Down
74 changes: 74 additions & 0 deletions .github/workflows/setup-wizard-e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Setup wizard verification

on:
pull_request:
paths:
- 'packages/setupWizard/**'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: When a PR changes root Yarn configuration or workspace metadata, the setup CLI has no test gate because this workflow does not trigger and test.yml now excludes setup-sourcebot. Add the root package-manager files that affect installation and packing to this workflow's paths filter.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/setup-wizard-e2e.yml, line 6:

<comment>When a PR changes root Yarn configuration or workspace metadata, the setup CLI has no test gate because this workflow does not trigger and `test.yml` now excludes `setup-sourcebot`. Add the root package-manager files that affect installation and packing to this workflow's `paths` filter.</comment>

<file context>
@@ -0,0 +1,74 @@
+on:
+  pull_request:
+    paths:
+      - 'packages/setupWizard/**'
+      - 'packages/schemas/**'
+      - 'entrypoint.sh'
</file context>

- 'packages/schemas/**'
- 'entrypoint.sh'
- 'yarn.lock'
- '.github/workflows/setup-wizard-e2e.yml'
- '.github/workflows/release-setup-sourcebot.yml'
workflow_dispatch:

permissions:
contents: read

jobs:
platform:
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node: ['20.20.0', '22.22.0', '24.x']
runs-on: ${{ matrix.os }}
env:
PACKAGE_TRACKER_ANALYTICS: 'false'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: '24.x'
- run: corepack enable
- run: yarn install --immutable --mode=skip-build
- run: yarn rebuild node-pty
- run: yarn workspace @sourcebot/schemas build
- run: yarn workspace setup-sourcebot build
- name: Pack on the release runtime
shell: bash
env:
SETUP_TEST_TARBALL: ${{ runner.temp }}/setup-sourcebot.tgz
run: |
yarn workspace setup-sourcebot pack --out "$SETUP_TEST_TARBALL"
echo "SETUP_TEST_TARBALL=$SETUP_TEST_TARBALL" >> "$GITHUB_ENV"
- name: Select end-user test runtime
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: corepack enable
- run: yarn workspace setup-sourcebot test
- run: yarn workspace setup-sourcebot test:platform
- name: Linux minimum-runtime regression checks
if: runner.os == 'Linux' && matrix.node != '24.x'
working-directory: packages/setupWizard
run: node --test --test-concurrency=1 tests/e2e/wizard.test.mjs tests/e2e/collectors.test.mjs tests/e2e/docker.test.mjs tests/e2e/safety.test.mjs
- name: Linux packed-artifact and runtime checks
if: runner.os == 'Linux' && matrix.node == '24.x'
run: |
docker pull docker.sourcebot.dev/sourcebot-dev/sourcebot:latest
yarn workspace setup-sourcebot test:e2e
yarn workspace setup-sourcebot test:baseline
node packages/setupWizard/tests/e2e/packageManagers.mjs

setup-wizard-e2e:
if: always()
needs: [platform]
runs-on: ubuntu-latest
steps:
- name: Require every platform job
env:
RESULT: ${{ needs.platform.result }}
run: test "$RESULT" = success
4 changes: 3 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,6 @@ jobs:
run: yarn install --frozen-lockfile

- name: Test
run: yarn test
# The CLI has separate packed-artifact and Node-compatibility gates in setup-wizard-e2e.
# Keep the application workspaces on their existing runtime here.
run: yarn workspaces foreach --all --topological --exclude setup-sourcebot --exclude 'root-workspace-*' run test

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The root workspace is not excluded here because its Yarn candidate name is exactly root-workspace, not root-workspace-*. As a result, this command can run the root test script recursively, reintroducing the setup wizard tests and duplicating the workspace test fan-out; exclude root-workspace exactly.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/test.yml, line 46:

<comment>The root workspace is not excluded here because its Yarn candidate name is exactly `root-workspace`, not `root-workspace-*`. As a result, this command can run the root `test` script recursively, reintroducing the setup wizard tests and duplicating the workspace test fan-out; exclude `root-workspace` exactly.</comment>

<file context>
@@ -41,4 +41,6 @@ jobs:
-        run: yarn test
+        # The CLI has separate packed-artifact and Node-compatibility gates in setup-wizard-e2e.
+        # Keep the application workspaces on their existing runtime here.
+        run: yarn workspaces foreach --all --topological --exclude setup-sourcebot --exclude 'root-workspace-*' run test
</file context>
Suggested change
run: yarn workspaces foreach --all --topological --exclude setup-sourcebot --exclude 'root-workspace-*' run test
run: yarn workspaces foreach --all --topological --exclude setup-sourcebot --exclude root-workspace run test

3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added
- Added privacy-scoped setup wizard funnel and Docker startup-failure telemetry with deployment identity handoff, Node.js 20.20.0 support, and cross-platform end-to-end test coverage. [#1653](https://github.com/sourcebot-dev/sourcebot/pull/1653)

## [5.1.13] - 2026-09-12

### Fixed
Expand Down
28 changes: 27 additions & 1 deletion packages/setupWizard/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,35 @@ The wizard walks you through:

## Requirements

- Node.js 18+
- 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.
- Docker and Docker Compose

## Development tests

From the repository root, under Node 24:

```bash
yarn workspace @sourcebot/schemas build
yarn workspace setup-sourcebot build
yarn workspace setup-sourcebot test
yarn workspace setup-sourcebot test:e2e
yarn workspace setup-sourcebot test:node-compatibility
```

The E2E tests compile and pack the package, install it outside the repository,
drive its published binary in a PTY, inspect real SDK requests through a local TLS
collector, and clean up temporary installations. OpenSSL and Docker are required.
PR verification runs nine parallel OS/Node jobs (Linux, macOS, Windows × Node
20.20.0, 22.22.0, 24). Each job builds and packs on Node 24 before selecting its
test runtime. Linux runs the full CLI regression suite on each version; macOS and
Windows run unit/integration and platform smoke tests. Docker identity, baseline,
and package-manager checks run only in the Node 24 Linux job.
Release verification also runs `test:node-compatibility` against the exact publish
tarball; that command checks the older runtimes sequentially, including early
rejection on Node 18, 20.19, and 22.21. Node 24 is not the end-user minimum.
The runtime suite uses `docker.sourcebot.dev/sourcebot-dev/sourcebot:latest`
(override only the test image with `SETUP_TEST_SOURCEBOT_IMAGE`).

## Docs

Full deployment guide: [docs.sourcebot.dev/docs/deployment/docker-compose](https://docs.sourcebot.dev/docs/deployment/docker-compose)
14 changes: 14 additions & 0 deletions packages/setupWizard/bin.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env node
// Intersection of posthog-node and @inquirer/prompts runtime requirements.
const [major, minor] = process.versions.node.split('.').map(Number);
const supported = (major === 20 && minor >= 20) ||
(major === 22 && minor >= 22) || (major === 23 && minor >= 5) || major >= 24;
if (!supported) {
console.error('setup-sourcebot requires Node.js 20.20+, 22.22+, or 23.5+ (including Node.js 24+). Please upgrade Node.js.');
process.exitCode = 1;
} else {
import('./dist/index.js').catch(() => {
console.error('Unable to start setup-sourcebot. Please reinstall the package.');
process.exitCode = 1;
});
}
22 changes: 17 additions & 5 deletions packages/setupWizard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,43 @@
"url": "git+https://github.com/sourcebot-dev/sourcebot.git",
"directory": "packages/setupWizard"
},
"bin": "./dist/index.js",
"bin": "./bin.cjs",
"scripts": {
"build": "tsc",
"watch": "tsc --watch",
"dev": "tsx src/index.ts",
"prepublishOnly": "yarn build"
"prepublishOnly": "yarn build",
"test": "node --test tests/unit/*.test.mjs tests/integration/*.test.mjs",
"test:e2e": "node --test --test-concurrency=1 tests/e2e/*.test.mjs",
"test:platform": "node --test tests/e2e/platform.test.mjs",
"test:linux": "node tests/e2e/linux.mjs",
"test:runtime": "node --test tests/e2e/runtime.test.mjs",
"test:node-compatibility": "node tests/e2e/nodeCompatibility.mjs",
"test:baseline": "node tests/e2e/baseline.mjs",
"test:live": "node tests/e2e/liveSmoke.mjs"
},
"dependencies": {
"@inquirer/prompts": "^8.4.3",
"chalk": "^5.6.2",
"inquirer-select-pro": "^1.0.0-alpha.9",
"ora": "^9.4.0",
"posthog-node": "5.52.1",
"reo-census": "^1.2.10"
},
"devDependencies": {
"@sourcebot/schemas": "workspace:^",
"@types/node": "^22.7.5",
"@types/node": "^20.19.43",
"node-pty": "^1.1.0",
"tsx": "^4.21.0",
"typescript": "^5.6.2"
"typescript": "^5.6.2",
"undici": "^7"
},
"engines": {
"node": ">=18"
"node": "^20.20.0 || ^22.22.0 || >=23.5.0"
},
"files": [
"dist",
"bin.cjs",
"README.md"
]
}
22 changes: 19 additions & 3 deletions packages/setupWizard/src/azuredevops.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { confirm, input, password, select } from '@inquirer/prompts';
import { tabCheckbox as checkbox } from './tabCheckbox.js';
import { sourceSummary } from './telemetrySummary.js';
import { confirm, input, password, select } from './prompts.js';
import { checkbox } from './prompts.js';
import type { AzureDevOpsConnectionConfig } from '@sourcebot/schemas/v3/azuredevops.type';
import type { CollectResult, EnvVars } from './utils.js';
import { multiInput, note, toEnvKey } from './utils.js';
Expand Down Expand Up @@ -96,5 +97,20 @@ export async function collectAzureDevOpsConfig(connectionName: string): Promise<
});
}

return { connections: [{ config }], env };
return {
connections: [{ config }],
env,
telemetry: sourceSummary('azure_devops', {
deploymentType: deploymentType === 'cloud' ? 'cloud' : 'self_hosted',
credentialMode: 'personal_access_token',
scopeTypes: [
...(targets.includes('orgs') ? ['organizations' as const] : []),
...(targets.includes('projects') ? ['projects' as const] : []),
...(targets.includes('repos') ? ['repositories' as const] : []),
],
organizationCount: config.orgs?.length ?? 0,
projectCount: config.projects?.length ?? 0,
repositoryCount: config.repos?.length ?? 0,
}),
};
}
51 changes: 46 additions & 5 deletions packages/setupWizard/src/bitbucket.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { confirm, input, password, select } from '@inquirer/prompts';
import { tabCheckbox as checkbox } from './tabCheckbox.js';
import { sourceSummary } from './telemetrySummary.js';
import { confirm, input, password, select } from './prompts.js';
import { checkbox } from './prompts.js';
import type { BitbucketConnectionConfig } from '@sourcebot/schemas/v3/bitbucket.type';
import type { CollectResult, EnvVars } from './utils.js';
import { multiInput, note, toEnvKey } from './utils.js';
Expand Down Expand Up @@ -151,7 +152,25 @@ async function collectBitbucketCloud(
});
}

return { connections: [{ config }], env };
return {
connections: [{ config }],
env,
telemetry: sourceSummary('bitbucket', {
deploymentType: 'cloud',
credentialMode:
authMethod === 'api-token'
? 'api_token'
: authMethod === 'access-token'
? 'access_token'
: 'app_password',
scopeTypes: [
...(targets.includes('workspaces') ? ['workspaces' as const] : []),
...(targets.includes('repos') ? ['repositories' as const] : []),
],
workspaceCount: config.workspaces?.length ?? 0,
repositoryCount: config.repos?.length ?? 0,
}),
};
}

async function collectBitbucketServer(
Expand Down Expand Up @@ -208,7 +227,16 @@ async function collectBitbucketServer(

if (indexAll) {
config.all = true;
return { connections: [{ config }], env };
return {
connections: [{ config }],
env,
telemetry: sourceSummary('bitbucket', {
deploymentType: 'self_hosted',
credentialMode: 'http_access_token',
indexAll: true,
scopeTypes: ['all'],
}),
};
}

const targets = await checkbox<string>({
Expand All @@ -232,5 +260,18 @@ async function collectBitbucketServer(
});
}

return { connections: [{ config }], env };
return {
connections: [{ config }],
env,
telemetry: sourceSummary('bitbucket', {
deploymentType: 'self_hosted',
credentialMode: 'http_access_token',
scopeTypes: [
...(targets.includes('projects') ? ['projects' as const] : []),
...(targets.includes('repos') ? ['repositories' as const] : []),
],
projectCount: config.projects?.length ?? 0,
repositoryCount: config.repos?.length ?? 0,
}),
};
}
Loading
Loading