Speed up playwright and blackbox workflow#13348
Conversation
There was a problem hiding this comment.
Pull request overview
Updates the Playwright E2E GitHub Actions workflow to avoid installing OS-level browser dependencies during the job by relying on an updated CI base image, reducing cache-miss runtime significantly.
Changes:
- Bump the
ci-base-imagepinned digest to a version that includes Chromium system dependencies. - Drop
--with-depsfrompnpm exec playwright installto avoid slow apt dependency installation. - Remove the cache-hit fallback step that installed
libnss3.
5f22b74 to
84bc371
Compare
Byron
left a comment
There was a problem hiding this comment.
This seems to have the desired effect and CI is still green.
84bc371 to
3099c7c
Compare
18ad600 to
4c70ef8
Compare
3d00adc to
0cd33a5
Compare
0cd33a5 to
f167eb2
Compare
Parallelize independent build steps (Rust, SvelteKit, Playwright install, tauri-driver) so they run concurrently instead of sequentially. Track each background PID and wait individually so any failure correctly fails the step. Skip node setup, SvelteKit, and test steps on master pushes since those runs only exist to warm the Rust cache. Add paths-ignore to both workflows so PRs that only touch docs, scripts, config files, or unrelated crates (CLI, TUI, debugging tools) skip the e2e jobs entirely. Install only chromium and webkit (no Firefox) and run apt-get update before Playwright install to avoid stale package index 404s. Pass the cache-hit output via an env var instead of inline template expansion to avoid a zizmor code-injection finding. Upload artifacts only on failure instead of on every non-cancelled run.
f167eb2 to
f7786bf
Compare
| pnpm_pid=$! | ||
| pw_pid="" | ||
| if [ "$PLAYWRIGHT_CACHE_HIT" != "true" ]; then | ||
| (apt-get update && cd e2e && pnpm exec playwright install chromium webkit) & |
There was a problem hiding this comment.
This step runs apt-get update but then only executes playwright install chromium webkit (no --with-deps and no subsequent apt-get install). As written, the apt-get update doesn’t affect anything and just adds overhead. Either remove apt-get update or switch back to playwright install --with-deps chromium webkit if the goal is to refresh the package index before installing system deps.
| (apt-get update && cd e2e && pnpm exec playwright install chromium webkit) & | |
| (cd e2e && pnpm exec playwright install chromium webkit) & |
| - master | ||
| pull_request: | ||
| paths-ignore: | ||
| - "*.md" |
There was a problem hiding this comment.
paths-ignore uses the pattern *.md, which only matches Markdown files in the repo root. Markdown docs in subdirectories will still trigger this workflow despite being “docs-only” changes. Use **/*.md (or list doc directories explicitly) if you want to ignore Markdown changes anywhere in the repo.
| - "*.md" | |
| - "**/*.md" |
| - name: Setup node environment | ||
| uses: ./.github/actions/init-env-node | ||
| - name: Build CLI | ||
| run: cargo build -p gitbutler-cli | ||
| - name: Build SvelteKit | ||
| run: pnpm build:desktop -- --mode development | ||
| - name: Build Tauri | ||
| run: pnpm build:test | ||
| - name: Install tauri-driver | ||
| if: ${{ github.ref != 'refs/heads/master' }} | ||
| - name: Build CLI, SvelteKit, and tauri-driver | ||
| if: ${{ github.ref != 'refs/heads/master' }} | ||
| run: | | ||
| cargo build -p gitbutler-cli & | ||
| cargo_pid=$! | ||
| pnpm build:desktop -- --mode development & | ||
| pnpm_pid=$! | ||
| td_pid="" | ||
| if [ ! -e "$HOME/.cargo/bin/tauri-driver" ]; then | ||
| cargo install tauri-driver | ||
| cargo install tauri-driver & | ||
| td_pid=$! | ||
| fi | ||
| status=0 | ||
| wait "$cargo_pid" || status=1 | ||
| wait "$pnpm_pid" || status=1 | ||
| [ -n "$td_pid" ] && { wait "$td_pid" || status=1; } | ||
| exit "$status" | ||
| - name: Build Tauri | ||
| if: ${{ github.ref != 'refs/heads/master' }} | ||
| run: pnpm build:test | ||
| - name: Build CLI (cache warming) | ||
| if: ${{ github.ref == 'refs/heads/master' }} | ||
| run: cargo build -p gitbutler-cli |
There was a problem hiding this comment.
The master-branch skipping logic is based on github.ref ==/!= 'refs/heads/master', which also applies to workflow_dispatch runs (they often run with github.ref set to the selected branch, frequently master). As a result, manually dispatching this workflow to test a specific inputs.sha on master will skip Node setup and E2E execution and only do the cache-warming build. Consider gating the cache-warm-only path on github.event_name == 'push' && github.ref == 'refs/heads/master' so manual dispatch still runs the full test flow.
| - master | ||
| pull_request: | ||
| paths-ignore: | ||
| - "*.md" |
There was a problem hiding this comment.
paths-ignore uses the pattern *.md, which only matches Markdown files in the repo root. Markdown docs in subdirectories (e.g. apps/desktop/README.md, e2e/README.md, etc.) will still trigger this workflow even though they are “docs-only” changes. Use **/*.md (or add explicit doc directories) if the intent is to skip all Markdown-only changes.
| - "*.md" | |
| - "**/*.md" |
| - name: Setup node environment | ||
| uses: ./.github/actions/init-env-node | ||
| if: ${{ github.ref != 'refs/heads/master' }} | ||
| - id: get_playwright_version | ||
| uses: eviden-actions/get-playwright-version@c83e8a285b395cc1e3d99df43d4ddaa0c889d8ff # v1 | ||
| if: ${{ github.ref != 'refs/heads/master' }} | ||
| - name: Cache playwright binaries | ||
| if: ${{ github.ref != 'refs/heads/master' }} | ||
| uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 | ||
| id: playwright-cache | ||
| with: | ||
| path: | | ||
| ~/.cache/ms-playwright | ||
| key: ${{ runner.os }}-playwright-${{ steps.get_playwright_version.outputs.playwright-version }} | ||
| - run: cd e2e && pnpm exec playwright install --with-deps | ||
| if: ${{ steps.playwright-cache.outputs.cache-hit != 'true' && github.ref != 'refs/heads/master' }} | ||
| - run: apt-get update && apt-get install -y libnss3 | ||
| if: ${{ steps.playwright-cache.outputs.cache-hit == 'true' && github.ref != 'refs/heads/master' }} | ||
| name: Install missing deps after cache hit | ||
| - name: Build gitbutler-git | ||
| run: cargo build -p gitbutler-git | ||
| - name: Build but-server | ||
| run: cargo build -p but-server | ||
| - name: Build but-testing | ||
| run: cargo build -p but-testing | ||
| - name: Build SvelteKit | ||
| run: pnpm build:desktop | ||
| - name: Build Rust binaries, SvelteKit, and install Playwright | ||
| if: ${{ github.ref != 'refs/heads/master' }} | ||
| env: | ||
| PLAYWRIGHT_CACHE_HIT: ${{ steps.playwright-cache.outputs.cache-hit }} | ||
| run: | | ||
| cargo build -p gitbutler-git -p but-server -p but-testing & | ||
| cargo_pid=$! | ||
| pnpm build:desktop & | ||
| pnpm_pid=$! | ||
| pw_pid="" | ||
| if [ "$PLAYWRIGHT_CACHE_HIT" != "true" ]; then | ||
| (apt-get update && cd e2e && pnpm exec playwright install chromium webkit) & | ||
| pw_pid=$! | ||
| fi | ||
| status=0 | ||
| wait "$cargo_pid" || status=1 | ||
| wait "$pnpm_pid" || status=1 | ||
| [ -n "$pw_pid" ] && { wait "$pw_pid" || status=1; } | ||
| exit "$status" | ||
| - name: Build Rust binaries | ||
| if: ${{ github.ref == 'refs/heads/master' }} | ||
| run: cargo build -p gitbutler-git -p but-server -p but-testing |
There was a problem hiding this comment.
Several steps are gated with if: github.ref != 'refs/heads/master' / == 'refs/heads/master'. For workflow_dispatch, github.ref is typically still refs/heads/master, which means a manual dispatch will skip Node setup and the E2E tests and only do the cache-warming Rust build. If manual dispatch is meant to run the tests for the provided inputs.sha, change the conditions to key off github.event_name == 'push' && github.ref == 'refs/heads/master' for the cache-warming path (and run the full flow otherwise).
Parallelize independent build steps (Rust, SvelteKit, Playwright
install, tauri-driver) so they run concurrently instead of sequentially.
Skip node setup, SvelteKit, and test steps on master pushes since those
runs only exist to warm the Rust cache.
Add paths-ignore to both workflows so PRs that only touch docs, scripts,
config files, or unrelated crates (CLI, TUI, debugging tools) skip
the e2e jobs entirely.
Install only chromium and webkit (no Firefox) and run apt-get update
before Playwright install to avoid stale package index 404s.
Upload artifacts only on failure instead of on every non-cancelled run.