pcbjam/.github/workflows/ci-full-build.yml
Istvan Matejcsok e913bebdeb fix(e2e): route pcbnew-family specs to bundled Chromium on CI
The xvfb/WebGL fix (f37ddc4) took CI from 22 to 11 failures (identical on
Hetzner 27343415331 and Ubicloud 27343416511) — everything left is the
pcbnew family, still dying at wasm compile: pcbnew's ~190M debug module
exceeds SpiderMonkey's per-process code budget on x86-64 even with the
baseline-only JIT (the same module compiles on arm64, whose denser code
fits — which is why the local arm64 repro passed). No pref raises that
limit; V8 handles the module fine.

New CI-only 'chromium-ci' project (bundled Chromium, headless, SwiftShader
via --enable-unsafe-swiftshader) carries pcbnew/pcbnew-collab/load-pcb/
load-pcb-probe; the firefox project ignores them on CI. Workflows call the
new test:kicad:ci script which runs both projects. Local test:kicad is
unchanged (firefox everywhere, system Chrome for headed runs).

Validated under x86 emulation (linux/amd64 playwright image on Rosetta):
the pcbnew wizard test passes on chromium-ci in 23s against the fresh
v130-postprocessed 192M module.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 16:12:01 +02:00

142 lines
6.1 KiB
YAML

# Full KiCad WASM build (all 6 tools) + e2e on an ephemeral Hetzner ccx53.
# This is the main-branch CI — the ONLY push-triggered Hetzner workflow; the
# bench (wasm-opt-bench.yml) and feature-branch (ci.yml) workflows are
# workflow_dispatch-only to keep paid VM spend deliberate. Validated at ~1h15m
# (run 27280051992, was 4h05m): lifted docker CPU caps, pipelined host-side
# wasm-opt (KICAD_PIPELINE=1), self-built Binaryen v130. History and
# measurements in docs/ci-build-slowness-findings.md.
name: CI full build + e2e (Hetzner)
on:
push:
branches: ["main"]
# docs-only commits must not burn a ~1h15m Hetzner slot
paths-ignore: ["docs/**", "**.md"]
workflow_dispatch:
inputs:
binaryen_version: { description: "Binaryen version for the host asyncify+-O2 step", required: false, default: "130" }
concurrency:
group: wasm-opt-bench # share the one-Hetzner-slot lock with the sweeps
cancel-in-progress: false
jobs:
create-runner:
name: Create Hetzner runner
runs-on: ubuntu-latest
outputs:
label: ${{ steps.create.outputs.label }}
server_id: ${{ steps.create.outputs.server_id }}
steps:
- uses: Cyclenerd/hcloud-github-runner@v1
id: create
with:
mode: create
github_token: ${{ secrets.HETZNER_RUNNER_PAT }}
hcloud_token: ${{ secrets.HCLOUD_TOKEN }}
server_type: ccx53
location: nbg1
image: ubuntu-24.04
validate:
name: Build all tools + KiCad e2e
needs: create-runner
runs-on: ${{ needs.create-runner.outputs.label }}
timeout-minutes: 300
env:
KICAD_LOG_NESTED: "1"
BINARYEN_VERSION: ${{ inputs.binaryen_version || '130' }}
steps:
- name: Install system deps (Docker, git)
run: |
export DEBIAN_FRONTEND=noninteractive
sudo apt-get update
# xvfb: kicad e2e runs headed Firefox under a virtual display — headless
# Firefox cannot create any GL context on the GPU-less VM (see
# tests/playwright-kicad.config.ts CI prefs).
sudo apt-get install -y ca-certificates curl git libjemalloc2 xvfb
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" \
| sudo tee /etc/apt/sources.list.d/docker.list >/dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# toolchain for BINARYEN_BUILD_FROM_SOURCE (get-wasm-opt.sh)
sudo apt-get install -y cmake ninja-build g++
- uses: actions/checkout@v4
with: { submodules: recursive }
- uses: actions/setup-node@v4
with: { node-version: 20 }
# Full KiCad WASM build of ALL 6 tools, but the host-side asyncify + -O2 use
# Binaryen v130 (BINARYEN_VERSION in env → get-wasm-opt.sh forces that
# standalone release). 'all' = pcbnew eeschema calculator pl_editor
# symbol_editor gerbview, built in sequence.
- name: Build all KiCad tools WASM with Binaryen ${{ env.BINARYEN_VERSION }}
run: |
# Lift the docker-compose dev-Mac caps (10 CPUs / 32G): run 27226030304
# compiled on 10 of 32 cores with -j 32. Pipeline the host-side
# asyncify+-O2 with the next tool's container compile (KICAD_PIPELINE=1;
# wasm-opt only reaches ~350% CPU, the container is idle meanwhile).
# BINARYEN_CORES=16: -O2 is Amdahl-capped ~4 effective cores, and up to
# two postprocesses run concurrently next to the compile.
export KICAD_DOCKER_CPUS="$(nproc)" KICAD_DOCKER_MEM=110G
export KICAD_PIPELINE=1 BINARYEN_CORES=16
# Self-built wasm-opt: the official x86_64-linux tarball runs asyncify
# 4x slower than a stock gcc -O3+LTO build, identical output
# (A/B on this runner, run 27276830256). ~5 min build, instantly repaid.
export BINARYEN_BUILD_FROM_SOURCE=1
echo "Building ALL tools with BINARYEN_VERSION=${BINARYEN_VERSION}, compile -j $(nproc) on ${KICAD_DOCKER_CPUS} CPUs, pipelined wasm-opt"
./docker/build.sh all --build-deps -j "$(nproc)"
echo "wasm-opt used:"; ./scripts/common/get-wasm-opt.sh --version 2>/dev/null || true
ls -lh output/*.wasm
- name: Install test deps
working-directory: tests
run: npm ci
- name: Install Playwright browsers
working-directory: tests
run: npx playwright install --with-deps firefox chromium
- name: Stage KiCad WASM for tests
working-directory: tests
run: npm run setup:kicad
- name: KiCad e2e (npm run test:kicad:ci)
working-directory: tests
# xvfb-run: headed Firefox on a virtual display — WebGL needs GLX + Mesa
# llvmpipe, which headless Firefox can't reach on a GPU-less VM.
# test:kicad:ci adds the chromium-ci project: pcbnew's wasm exceeds
# SpiderMonkey's x86-64 code budget, so those specs run on Chromium.
run: xvfb-run -a npm run test:kicad:ci
- name: Upload test logs & screenshots
if: always()
uses: actions/upload-artifact@v4
with:
name: full-build-e2e-${{ github.run_id }}
path: |
tests/logs/**
tests/test-results/**
tests/playwright-report/**
if-no-files-found: ignore
delete-runner:
name: Delete Hetzner runner
needs: [create-runner, validate]
runs-on: ubuntu-latest
if: always()
steps:
- uses: Cyclenerd/hcloud-github-runner@v1
with:
mode: delete
github_token: ${{ secrets.HETZNER_RUNNER_PAT }}
hcloud_token: ${{ secrets.HCLOUD_TOKEN }}
name: ${{ needs.create-runner.outputs.label }}
server_id: ${{ needs.create-runner.outputs.server_id }}