mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-08-17 18:25:42 +02:00
- split the single windows e2e job into parallel jobs: gate (pure-node selftests, no build), verify (build + verify-all), playwright (build + renderer suite). verify and playwright run concurrently so wall-clock is max(verify, playwright), not their sum - build the UNPACKED app on the gate path (electron-builder --dir via a new -DirOnly switch in build-app-win.ps1), skipping the ~2min NSIS LZMA compression. verify-all drives win-unpacked\OpenSwarm.exe; afterPack + locale paks still run in the pack phase, and verify-update-feed skips cleanly when no installer feed is present - cache the heavy build inputs (bundled Python env, uv, MCP bundles) + npm across runs, keyed on their source manifests; the build script already skips any input already on disk, so warm builds are fast - move the destructive installer cycle to its own job gated off routine pushes (runs on PR-to-main / dispatch; release-windows.yml covers v* tags) - apply the same caching to dogfood (shares cache keys, so the two warm each other)
281 lines
10 KiB
YAML
281 lines
10 KiB
YAML
name: E2E (packaged app, Windows)
|
|
|
|
# Fast-feedback packaged-app gate, Windows-only. Split into parallel jobs so the
|
|
# push wall-clock stays well under ~10 min:
|
|
# gate - cheap pure-node selftests (no build): mutation gate + preflight
|
|
# Layers 1-5. Fails the "tests that test the tests" fast.
|
|
# verify - build the UNPACKED app (electron-builder --dir, which skips the
|
|
# slow ~2min NSIS LZMA compression) and run the deterministic
|
|
# verify-all gate against win-unpacked\OpenSwarm.exe.
|
|
# playwright - build the unpacked app and run the renderer-level Playwright e2e.
|
|
# installer - full NSIS build + destructive install->verify->uninstall. The
|
|
# heaviest leg, so it runs only on PR-to-main / dispatch (NOT on
|
|
# routine pushes); release-windows.yml covers it on v* tags.
|
|
# verify + playwright run concurrently; both reuse cached heavy build inputs
|
|
# (bundled Python env, uv, MCP bundles, npm) so warm builds are fast - the build
|
|
# script skips any input already on disk.
|
|
#
|
|
# macOS legs were removed (runner starvation + untriageable mac-only failures);
|
|
# re-add when a Mac maintainer can own them. Real Win10 coverage still needs the
|
|
# SELF-HOSTED e2e-win10 job (repo var WIN10_SELF_HOSTED=true + a
|
|
# [self-hosted, windows, win10] runner).
|
|
|
|
on:
|
|
push:
|
|
branches: [eric/lock]
|
|
paths: &build-paths
|
|
- 'electron/**'
|
|
- 'frontend/**'
|
|
- 'backend/**'
|
|
- 'e2e/**'
|
|
- 'scripts/build-app**'
|
|
- 'scripts/build-python-env**'
|
|
- 'scripts/fetch-router**'
|
|
- 'scripts/ci/**'
|
|
- '.github/workflows/e2e.yml'
|
|
pull_request:
|
|
branches: [main]
|
|
paths: *build-paths
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
env:
|
|
CSC_IDENTITY_AUTO_DISCOVERY: 'false'
|
|
GOOGLE_OAUTH_CLIENT_ID: 'e2e-placeholder.apps.googleusercontent.com'
|
|
GOOGLE_OAUTH_CLIENT_SECRET: 'e2e-placeholder-secret'
|
|
|
|
jobs:
|
|
# Pure-node, no build: cheap enough to always run and fail fast.
|
|
gate:
|
|
runs-on: windows-latest
|
|
timeout-minutes: 15
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20.18.1'
|
|
- name: Gate selftest (mutation)
|
|
shell: bash
|
|
run: node scripts/ci/selftest-gate.js
|
|
- name: Preflight selftest (Layers 1+2)
|
|
shell: bash
|
|
run: node scripts/ci/selftest-preflight.js
|
|
- name: Preflight failure rigs (Layer 3)
|
|
shell: bash
|
|
run: node scripts/ci/verify-preflight-rigs.js
|
|
- name: Preflight race / cache (Layer 4)
|
|
shell: bash
|
|
run: node scripts/ci/verify-preflight-race.js
|
|
- name: Pairwise generator selftest (covering-array math)
|
|
shell: bash
|
|
run: node scripts/ci/selftest-pairwise.js
|
|
- name: Preflight matrix (normal + hostile-env scenarios)
|
|
shell: bash
|
|
run: |
|
|
node scripts/ci/verify-preflight.js
|
|
OPENSWARM_TEST_NETWORK=blocked node scripts/ci/verify-preflight.js
|
|
OPENSWARM_TEST_APPDATA=readonly node scripts/ci/verify-preflight.js
|
|
OPENSWARM_TEST_LANG=de-DE node scripts/ci/verify-preflight.js
|
|
|
|
# Build the unpacked app + run the deterministic gate.
|
|
verify:
|
|
runs-on: windows-latest
|
|
timeout-minutes: 30
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20.18.1'
|
|
cache: npm
|
|
cache-dependency-path: |
|
|
electron/package-lock.json
|
|
frontend/package-lock.json
|
|
- uses: actions/setup-python@v5
|
|
with:
|
|
python-version: '3.13'
|
|
- name: Cache bundled Python env
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: electron/python-env
|
|
key: pyenv-win-${{ hashFiles('scripts/build-python-env-win.ps1', 'backend/requirements.txt') }}
|
|
- name: Cache uv binaries
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: backend/uv-bin
|
|
key: uvbin-win-${{ hashFiles('scripts/build-app-win.ps1') }}
|
|
- name: Cache MCP bundles
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: backend/mcp-bundles
|
|
key: mcpbundles-win-${{ hashFiles('scripts/build-app-win.ps1') }}
|
|
- name: Build packaged app (unpacked, no installer)
|
|
shell: pwsh
|
|
run: pwsh -NoProfile -File scripts/build-app-win.ps1 -DirOnly
|
|
- name: Deterministic gate (verify-all)
|
|
shell: bash
|
|
run: node scripts/ci/verify-all.js
|
|
|
|
# Build the unpacked app + run the Playwright renderer suite, concurrently with verify.
|
|
playwright:
|
|
runs-on: windows-latest
|
|
timeout-minutes: 30
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20.18.1'
|
|
cache: npm
|
|
cache-dependency-path: |
|
|
electron/package-lock.json
|
|
frontend/package-lock.json
|
|
e2e/package-lock.json
|
|
- uses: actions/setup-python@v5
|
|
with:
|
|
python-version: '3.13'
|
|
- name: Cache bundled Python env
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: electron/python-env
|
|
key: pyenv-win-${{ hashFiles('scripts/build-python-env-win.ps1', 'backend/requirements.txt') }}
|
|
- name: Cache uv binaries
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: backend/uv-bin
|
|
key: uvbin-win-${{ hashFiles('scripts/build-app-win.ps1') }}
|
|
- name: Cache MCP bundles
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: backend/mcp-bundles
|
|
key: mcpbundles-win-${{ hashFiles('scripts/build-app-win.ps1') }}
|
|
- name: Build packaged app (unpacked, no installer)
|
|
shell: pwsh
|
|
run: pwsh -NoProfile -File scripts/build-app-win.ps1 -DirOnly
|
|
- name: Install e2e deps
|
|
shell: bash
|
|
working-directory: e2e
|
|
env:
|
|
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1'
|
|
run: npm ci
|
|
- name: GUI hand selftest (MCP)
|
|
shell: bash
|
|
working-directory: e2e
|
|
run: node mcp/selftest.js
|
|
- name: Run E2E (Playwright)
|
|
shell: bash
|
|
working-directory: e2e
|
|
run: npm test
|
|
- name: Upload E2E results
|
|
if: always()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: e2e-results
|
|
path: e2e/results.json
|
|
if-no-files-found: ignore
|
|
retention-days: 14
|
|
# Per-test traces: playwright-trace.zip, events.jsonl, mousepath.jsonl,
|
|
# backend.log.tail - always uploaded so a failed run is debuggable.
|
|
- name: Upload E2E visibility traces
|
|
if: always()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: e2e-traces
|
|
path: e2e/traces/
|
|
if-no-files-found: ignore
|
|
retention-days: 14
|
|
|
|
# Heaviest leg: full NSIS installer + destructive install->verify->uninstall on
|
|
# a clean runner. Skip on routine pushes; run on PRs into main + manual dispatch.
|
|
installer:
|
|
if: github.event_name != 'push'
|
|
runs-on: windows-latest
|
|
timeout-minutes: 45
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20.18.1'
|
|
cache: npm
|
|
cache-dependency-path: |
|
|
electron/package-lock.json
|
|
frontend/package-lock.json
|
|
- uses: actions/setup-python@v5
|
|
with:
|
|
python-version: '3.13'
|
|
- name: Cache bundled Python env
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: electron/python-env
|
|
key: pyenv-win-${{ hashFiles('scripts/build-python-env-win.ps1', 'backend/requirements.txt') }}
|
|
- name: Cache uv binaries
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: backend/uv-bin
|
|
key: uvbin-win-${{ hashFiles('scripts/build-app-win.ps1') }}
|
|
- name: Cache MCP bundles
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: backend/mcp-bundles
|
|
key: mcpbundles-win-${{ hashFiles('scripts/build-app-win.ps1') }}
|
|
- name: Build packaged app (full NSIS installer)
|
|
shell: pwsh
|
|
run: pwsh -NoProfile -File scripts/build-app-win.ps1
|
|
- name: Installer cycle (clean runner)
|
|
shell: pwsh
|
|
run: node scripts/ci/verify-installer.js --destructive
|
|
|
|
# Real Windows 10 coverage. Skipped unless a self-hosted Win10 runner exists
|
|
# and WIN10_SELF_HOSTED=true (repo variable). Mirrors the windows steps above.
|
|
e2e-win10:
|
|
if: ${{ vars.WIN10_SELF_HOSTED == 'true' }}
|
|
runs-on: [self-hosted, windows, win10]
|
|
timeout-minutes: 90
|
|
env:
|
|
CSC_IDENTITY_AUTO_DISCOVERY: 'false'
|
|
GOOGLE_OAUTH_CLIENT_ID: 'e2e-placeholder.apps.googleusercontent.com'
|
|
GOOGLE_OAUTH_CLIENT_SECRET: 'e2e-placeholder-secret'
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20.18.1'
|
|
- uses: actions/setup-python@v5
|
|
with:
|
|
python-version: '3.13'
|
|
- name: Gate selftest (mutation)
|
|
shell: bash
|
|
run: node scripts/ci/selftest-gate.js
|
|
- name: Preflight selftest + rigs + race + matrix (Layers 1-5)
|
|
shell: bash
|
|
run: |
|
|
node scripts/ci/selftest-preflight.js
|
|
node scripts/ci/verify-preflight-rigs.js
|
|
node scripts/ci/verify-preflight-race.js
|
|
node scripts/ci/verify-preflight.js
|
|
OPENSWARM_TEST_NETWORK=blocked node scripts/ci/verify-preflight.js
|
|
OPENSWARM_TEST_APPDATA=readonly node scripts/ci/verify-preflight.js
|
|
- name: Build packaged app (Windows)
|
|
shell: pwsh
|
|
run: pwsh -NoProfile -File scripts/build-app-win.ps1
|
|
- name: Deterministic gate (verify-all)
|
|
shell: bash
|
|
run: node scripts/ci/verify-all.js
|
|
- name: Install e2e deps
|
|
shell: bash
|
|
working-directory: e2e
|
|
env:
|
|
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1'
|
|
run: npm ci
|
|
- name: GUI hand selftest (MCP)
|
|
shell: bash
|
|
working-directory: e2e
|
|
run: node mcp/selftest.js
|
|
- name: Run E2E (Playwright)
|
|
shell: bash
|
|
working-directory: e2e
|
|
run: npm test
|
|
- name: Installer cycle (clean runner)
|
|
shell: pwsh
|
|
run: node scripts/ci/verify-installer.js --destructive
|