From 2aa39ca1a66644c4cc781a8656239613c94e0eeb Mon Sep 17 00:00:00 2001 From: Vito Date: Sun, 18 Oct 2026 17:34:57 -0700 Subject: [PATCH] ci: run Firefox and WebKit page workflows in parallel jobs (#229) * ci: run Firefox and WebKit page workflows in parallel jobs The viewerjs job ran the Chromium/touch coverage pass and then the Firefox and WebKit page workflows serially on one runner. The suite grew from 396 to 496 tests in #227 and the job passed its 25 minute cap with every test green, which #227 papered over by raising the budget to 40 minutes. Split the workflow into a frontend-coverage job, a fail-fast: false matrix with one runner per browser, and an aggregate viewerjs job that needs both and fails unless each result is success. The aggregate keeps the exact "viewerjs" context that branch protection requires, so .github/branch-protection.json is unchanged. Browser projects, the single Playwright worker and per-test timeouts are untouched. Coverage keeps the frontend-test-reports artifact; Firefox and WebKit traces move to browser-traces-. Closes #228. * ci: keep the frontend coverage job on a 25 minute budget Merging main carried the 40 minute budget from #227 onto the new frontend-coverage job. That job no longer runs the Firefox and WebKit workflows and took 9m31s in run 39178111649 at 396 tests, so the original 25 minute budget is the right one for all three jobs. --- .github/workflows/viewerjs-check.yml | 62 +++++++++++++++++++++++++--- TESTING.md | 11 +++-- 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/.github/workflows/viewerjs-check.yml b/.github/workflows/viewerjs-check.yml index 4dc9411..72bf93b 100644 --- a/.github/workflows/viewerjs-check.yml +++ b/.github/workflows/viewerjs-check.yml @@ -11,9 +11,10 @@ permissions: contents: read jobs: - viewerjs: + frontend-coverage: + name: frontend coverage (chromium and touch) runs-on: ubuntu-latest - timeout-minutes: 40 + timeout-minutes: 25 steps: - uses: actions/checkout@v7 - uses: actions/setup-python@v7 @@ -30,12 +31,10 @@ jobs: - run: npm ci --prefix tools/vendor --ignore-scripts - run: npm run --prefix tools/vendor check - run: npm run --prefix tools/vendor test - - run: npx --prefix tools/vendor playwright install --with-deps chromium firefox webkit + - run: npx --prefix tools/vendor playwright install --with-deps chromium - name: Frontend unit, viewer, workflow, and coverage checks run: npm run --prefix tools/vendor test:coverage - - name: Firefox and WebKit page workflows - run: npm run --prefix tools/vendor test:workflows -- --project firefox --project webkit - - name: Upload browser traces and frontend coverage + - name: Upload frontend coverage and Chromium traces if: always() uses: actions/upload-artifact@v7 with: @@ -45,3 +44,54 @@ jobs: coverage/js/ !coverage/js/raw/** retention-days: 14 + + browser-workflows: + name: page workflows (${{ matrix.browser }}) + runs-on: ubuntu-latest + timeout-minutes: 25 + strategy: + fail-fast: false + matrix: + browser: [firefox, webkit] + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-python@v7 + with: + python-version: '3.12' + cache: pip + cache-dependency-path: requirements-dev.txt + - run: python -m pip install -r requirements-dev.txt + - uses: actions/setup-node@v7 + with: + node-version: '24' + cache: npm + cache-dependency-path: tools/vendor/package-lock.json + - run: npm ci --prefix tools/vendor --ignore-scripts + - run: npx --prefix tools/vendor playwright install --with-deps ${{ matrix.browser }} + - name: Page workflows in ${{ matrix.browser }} + run: npm run --prefix tools/vendor test:workflows -- --project ${{ matrix.browser }} + - name: Upload browser traces + if: always() + uses: actions/upload-artifact@v7 + with: + name: browser-traces-${{ matrix.browser }} + path: tools/vendor/test-results/ + retention-days: 14 + + # Branch protection requires the exact context "viewerjs". This job keeps that + # name and fails unless every frontend job above succeeded, including when one + # was cancelled or skipped. + viewerjs: + needs: [frontend-coverage, browser-workflows] + if: always() + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Require every frontend job to succeed + env: + COVERAGE_RESULT: ${{ needs.frontend-coverage.result }} + WORKFLOWS_RESULT: ${{ needs.browser-workflows.result }} + run: | + echo "frontend-coverage: $COVERAGE_RESULT" + echo "browser-workflows: $WORKFLOWS_RESULT" + test "$COVERAGE_RESULT" = success && test "$WORKFLOWS_RESULT" = success diff --git a/TESTING.md b/TESTING.md index 5dd8cea..fcce8af 100644 --- a/TESTING.md +++ b/TESTING.md @@ -99,9 +99,14 @@ the baseline updater. Raise floors with `npm run --prefix tools/vendor coverage:update`; it reruns the suites and cannot lower an existing floor. Review baseline changes like code changes. -The `viewerjs` check runs on every PR, including backend-only changes. GitHub -artifacts named `frontend-test-reports` contain HTML coverage, a JSON summary, -and failure screenshots/traces. Open traces with Playwright's `show-trace` tool. +The `viewerjs` check runs on every PR, including backend-only changes. It is an +aggregate job that passes only when the `frontend coverage (chromium and touch)` +job and both `page workflows (firefox)` and `page workflows (webkit)` jobs +succeed; the browsers run on separate runners in parallel. GitHub artifacts +named `frontend-test-reports` contain HTML coverage, a JSON summary, and the +Chromium/touch failure screenshots/traces; `browser-traces-firefox` and +`browser-traces-webkit` hold the other browsers' traces. Open traces with +Playwright's `show-trace` tool. The real-host suite covers both Classic and Nodes 2.0 startup, switching both ways, actual database prompt selection, execution-text serialization, workflow