ci: run E2E tests on every PR, surface on release (non-blocking) (#842)

This commit is contained in:
Brennan Benson 2026-04-19 13:48:27 -07:00 committed by GitHub
parent 76d4b9a435
commit 660b5f4149
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 79 additions and 0 deletions

59
.github/workflows/e2e.yml vendored Normal file
View file

@ -0,0 +1,59 @@
name: E2E
on:
workflow_call:
inputs:
ref:
description: Ref to check out (defaults to the calling workflow's ref)
required: false
type: string
jobs:
e2e:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ inputs.ref || github.ref }}
# Why: electron-vite's globalSetup invokes a full app build, which
# compiles native modules via node-gyp. Mirrors the install step in
# pr.yml's verify job so E2E doesn't hit missing-toolchain errors.
- name: Install native build tools
run: sudo apt-get update && sudo apt-get install -y build-essential python3
# Why: Electron on Linux needs an X display even when the app
# suppresses mainWindow.show() via ORCA_E2E_HEADLESS. xvfb provides a
# virtual framebuffer so Chromium can initialize without a real display.
- name: Install xvfb
run: sudo apt-get install -y xvfb
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 24
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
run_install: false
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run E2E tests
run: xvfb-run --auto-servernum pnpm run test:e2e
# Why: Playwright retains traces/screenshots only on failure. Uploading
# them as an artifact makes post-mortem debugging on CI possible without
# re-running locally.
- name: Upload Playwright traces
if: failure()
uses: actions/upload-artifact@v4
with:
name: playwright-traces
path: test-results/
retention-days: 7
if-no-files-found: ignore

View file

@ -43,3 +43,6 @@ jobs:
- name: Build
run: pnpm build
e2e:
uses: ./.github/workflows/e2e.yml

View file

@ -63,6 +63,18 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Why: E2E runs alongside the release for visibility (failures surface as a
# red check on the tag), but it is NOT in `release`'s needs list. Releases
# already take a while and the suite is already a required check on PRs, so
# gating here would mostly just delay shipping without adding much signal.
# Matches the pattern used by noqa's app deploy, which runs E2E with
# continue-on-error so failures are visible but don't block the deploy.
e2e:
needs: resolve-release
uses: ./.github/workflows/e2e.yml
with:
ref: ${{ needs.resolve-release.outputs.ref }}
release:
needs:
- resolve-release

View file

@ -26,6 +26,11 @@ export default defineConfig({
// substantially. The few visible-window tests that still rely on real
// pointer interaction are marked serial in their spec file instead.
fullyParallel: true,
// Why: Playwright defaults to workers=1 on CI, which would serialize all
// specs on the ubuntu-latest runner (4 vCPUs) and waste headroom. Each test
// launches an isolated Electron instance with its own userData dir, so they
// don't share state — we can safely fan out to match the runner's vCPU count.
workers: process.env.CI ? 4 : undefined,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 1 : 0,
reporter: 'list',