diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index d06bbeb298b..1f717df74e4 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -70,12 +70,13 @@ jobs: # Why: building here avoids parallel builds inside Playwright globalSetup; # paired-browser specs also need the standalone web bundle. - - name: Build Electron app for E2E + - name: Build E2E outputs env: VITE_EXPOSE_STORE: 'true' run: | npx electron-vite build --mode e2e pnpm run build:web-from-renderer + pnpm run build:relay - name: Upload E2E build output uses: actions/upload-artifact@v7 @@ -174,7 +175,7 @@ jobs: # ORCA_E2E_FORWARD_APP_LOGS keeps startup failures visible when Electron # launches but never creates a BrowserWindow. - name: Run E2E tests (${{ matrix.shard_name }}) - run: xvfb-run --auto-servernum env SKIP_BUILD=1 ORCA_E2E_FORWARD_APP_LOGS=1 ORCA_E2E_WEB_CLIENT=1 pnpm run test:e2e --shard=${{ matrix.shard }} + run: xvfb-run --auto-servernum env SKIP_BUILD=1 ORCA_E2E_FORWARD_APP_LOGS=1 ORCA_E2E_WEB_CLIENT=1 ORCA_RELAY_PATH="$GITHUB_WORKSPACE/out/relay" pnpm run test:e2e --shard=${{ matrix.shard }} # Why: Playwright retains traces/screenshots only on failure. Uploading # them as an artifact makes post-mortem debugging on CI possible without @@ -240,7 +241,7 @@ jobs: echo "Changed startup-readiness specs are owned by the dedicated live lane." exit 0 fi - E2E_ENV=(SKIP_BUILD=1 ORCA_E2E_FORWARD_APP_LOGS=1 ORCA_E2E_WEB_CLIENT=1) + E2E_ENV=(SKIP_BUILD=1 ORCA_E2E_FORWARD_APP_LOGS=1 ORCA_E2E_WEB_CLIENT=1 ORCA_RELAY_PATH="$GITHUB_WORKSPACE/out/relay") if printf '%s\n' "${TEST_FILES[@]}" | grep -qx 'tests/e2e/ephemeral-vm-provisioned-root.spec.ts'; then E2E_ENV+=(ORCA_E2E_SSH_DOCKER=1) fi diff --git a/tests/e2e/global-setup.ts b/tests/e2e/global-setup.ts index 77e4e22079d..cd5d9b3c4e0 100644 --- a/tests/e2e/global-setup.ts +++ b/tests/e2e/global-setup.ts @@ -33,6 +33,7 @@ export default function globalSetup(): void { const outMain = path.join(root, 'out', 'main', 'index.js') const outCli = path.join(root, 'out', 'cli', 'index.js') const outWeb = path.join(root, 'out', 'web', 'web-index.html') + const outLinuxRelay = path.join(root, 'out', 'relay', 'linux-x64', 'relay.js') // ── 1. Build the Electron app ────────────────────────────────────── if (process.env.SKIP_BUILD && existsSync(outMain)) { @@ -83,15 +84,17 @@ export default function globalSetup(): void { process.env.ORCA_E2E_NESTED_RUNTIME_SSH === '1' || (process.env.ORCA_E2E_SKILL_STAGING === '1' && Boolean(process.env.ORCA_E2E_SKILL_SSH_HOST)) ) { - // Why: the SSH specs deploy Orca's relay from out/relay. The - // normal Electron E2E build does not produce that bundle, so build it only - // for explicit SSH runs. - console.error('[e2e] Building SSH relay bundle for SSH E2E...') - execSync('pnpm run build:relay', { - cwd: root, - stdio: 'inherit', - timeout: 120_000 - }) + if (process.env.SKIP_BUILD && existsSync(outLinuxRelay)) { + console.error('[e2e] SKIP_BUILD set and SSH relay bundle exists — skipping relay build') + } else { + // Why: explicit SSH specs need deployable Relay outputs in source-tree runs. + console.error('[e2e] Building SSH relay bundle for SSH E2E...') + execSync('pnpm run build:relay', { + cwd: root, + stdio: 'inherit', + timeout: 120_000 + }) + } } if (process.env.ORCA_E2E_SSH_DOCKER === '1' || process.env.ORCA_E2E_NESTED_RUNTIME_SSH === '1') { console.error('[e2e] Preparing Docker OpenSSH fixture image...')