ci: 🎡 -o1 & test workers
This commit is contained in:
parent
e203c74a68
commit
5df7f40b3c
4 changed files with 55 additions and 14 deletions
35
.github/workflows/ci-ubicloud.yml
vendored
35
.github/workflows/ci-ubicloud.yml
vendored
|
|
@ -1,5 +1,5 @@
|
||||||
# The build + e2e CI: full KiCad WASM build (all 6 tools, Binaryen 130, host-side
|
# The build + e2e CI: full KiCad WASM build (all 6 tools, Binaryen 130, host-side
|
||||||
# asyncify only — the -O2 pass is skipped via ASYNCIFY_ONLY=1) + wxWidgets e2e
|
# asyncify + a lighter wasm-opt -O1 shrink pass via BINARYEN_OPT_LEVEL) + wxWidgets e2e
|
||||||
# (291 tests) + KiCad e2e (38 tests) on a Ubicloud runner. Runs on pushes to
|
# (291 tests) + KiCad e2e (38 tests) on a Ubicloud runner. Runs on pushes to
|
||||||
# main/ubicloud-ci and on PRs against main.
|
# main/ubicloud-ci and on PRs against main.
|
||||||
# Replaced the ephemeral-Hetzner-VM workflows (ci-full-build.yml / ci.yml,
|
# Replaced the ephemeral-Hetzner-VM workflows (ci-full-build.yml / ci.yml,
|
||||||
|
|
@ -38,10 +38,14 @@ jobs:
|
||||||
env:
|
env:
|
||||||
KICAD_LOG_NESTED: "1"
|
KICAD_LOG_NESTED: "1"
|
||||||
BINARYEN_VERSION: ${{ inputs.binaryen_version || '130' }}
|
BINARYEN_VERSION: ${{ inputs.binaryen_version || '130' }}
|
||||||
# Skip the heavy wasm-opt -O2 pass (scripts/common/apply-asyncify.sh:124):
|
# Use the lighter wasm-opt -O1 shrink pass instead of -O2
|
||||||
# stops after the asyncify pass. The full e2e suite below validates that
|
# (scripts/common/apply-asyncify.sh). -O1 still runs CoalesceLocals, so the
|
||||||
# the non-O2 wasm runs correctly in Chrome/Firefox.
|
# asyncify-instrumented coroutine functions stay under V8's per-function
|
||||||
ASYNCIFY_ONLY: "1"
|
# locals limit: it produces the same ~187 MB pcbnew.wasm as -O2 and is green
|
||||||
|
# on the load-pcb chromium-ci spec, but is a faster pass. (Skipping the
|
||||||
|
# optimization entirely via ASYNCIFY_ONLY=1 shipped a 336 MB wasm that
|
||||||
|
# crashed headless Chromium — that flag is benchmark-only, not for e2e.)
|
||||||
|
BINARYEN_OPT_LEVEL: "-O1"
|
||||||
# Stable docker-compose project → deterministic build-cache volume name
|
# Stable docker-compose project → deterministic build-cache volume name
|
||||||
# (kicad-wasm-ci_kicad-build-cache) for the deps cache below.
|
# (kicad-wasm-ci_kicad-build-cache) for the deps cache below.
|
||||||
COMPOSE_PROJECT_NAME: kicad-wasm-ci
|
COMPOSE_PROJECT_NAME: kicad-wasm-ci
|
||||||
|
|
@ -86,7 +90,7 @@ jobs:
|
||||||
|
|
||||||
# Same build recipe as ci-full-build.yml: full KiCad WASM build of ALL 6
|
# Same build recipe as ci-full-build.yml: full KiCad WASM build of ALL 6
|
||||||
# tools, host-side asyncify on Binaryen v130 (BINARYEN_VERSION in env →
|
# tools, host-side asyncify on Binaryen v130 (BINARYEN_VERSION in env →
|
||||||
# get-wasm-opt.sh); the -O2 pass is skipped (ASYNCIFY_ONLY=1 in job env).
|
# get-wasm-opt.sh) + a lighter -O1 shrink pass (BINARYEN_OPT_LEVEL in job env).
|
||||||
# 'all' = pcbnew eeschema calculator pl_editor symbol_editor gerbview,
|
# 'all' = pcbnew eeschema calculator pl_editor symbol_editor gerbview,
|
||||||
# built in sequence. --build-deps short-circuits on a cache hit.
|
# built in sequence. --build-deps short-circuits on a cache hit.
|
||||||
- name: Build all KiCad tools WASM with Binaryen ${{ env.BINARYEN_VERSION }}
|
- name: Build all KiCad tools WASM with Binaryen ${{ env.BINARYEN_VERSION }}
|
||||||
|
|
@ -117,6 +121,25 @@ jobs:
|
||||||
docker run --rm -v kicad-wasm-ci_kicad-build-cache:/bw -v "$PWD/deps-cache":/cache \
|
docker run --rm -v kicad-wasm-ci_kicad-build-cache:/bw -v "$PWD/deps-cache":/cache \
|
||||||
alpine sh -c 'cd /bw && tar czf /cache/deps.tar.gz sysroot stamps'
|
alpine sh -c 'cd /bw && tar czf /cache/deps.tar.gz sysroot stamps'
|
||||||
|
|
||||||
|
# Cache the host wxWidgets build (build-wasm/wxwidgets, ~11 min, incremental
|
||||||
|
# but uncached) keyed on the wx submodule SHA + the build script/versions.
|
||||||
|
# On a hit, touch the tree so make treats the restored objects as current
|
||||||
|
# (same SHA ⇒ identical sources), so build-wx-wasm.sh just relinks fast.
|
||||||
|
- name: wx submodule sha
|
||||||
|
id: wxsha
|
||||||
|
run: echo "sha=$(git -C wxwidgets rev-parse HEAD)" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Restore wx build cache
|
||||||
|
id: wx-cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: build-wasm/wxwidgets
|
||||||
|
key: wx-${{ runner.os }}-${{ steps.wxsha.outputs.sha }}-${{ hashFiles('scripts/build-wx-wasm.sh','scripts/common/versions.sh') }}
|
||||||
|
|
||||||
|
- name: Mark restored wx objects current
|
||||||
|
if: steps.wx-cache.outputs.cache-hit == 'true'
|
||||||
|
run: find build-wasm/wxwidgets -exec touch {} +
|
||||||
|
|
||||||
# Host-side wxWidgets build producing the wx test apps for `npm run test`
|
# Host-side wxWidgets build producing the wx test apps for `npm run test`
|
||||||
# (separate from the in-docker wxWidgets that KiCad links against).
|
# (separate from the in-docker wxWidgets that KiCad links against).
|
||||||
# Auto-installs emsdk into tools/ on first run.
|
# Auto-installs emsdk into tools/ on first run.
|
||||||
|
|
|
||||||
|
|
@ -128,18 +128,30 @@ if [[ "${ASYNCIFY_ONLY:-0}" == "1" ]]; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Post-asyncify shrink pass. Asyncify emits deliberately verbose instrumentation
|
||||||
|
# (spills every live local) and relies on the optimizer to coalesce it back down
|
||||||
|
# under V8's per-function locals limit — without it, large coroutine-entry
|
||||||
|
# functions silently stall (and on newer Chromium hard-crash the renderer while
|
||||||
|
# loading a heavy board) in Chrome's V8. See docs/debugging/DEBUG.md §6-7.
|
||||||
|
#
|
||||||
|
# Level is configurable via BINARYEN_OPT_LEVEL: -O1 already runs CoalesceLocals
|
||||||
|
# and is sufficient (measured: same ~187 MB / 64 MB-gzip output as -O2 on pcbnew,
|
||||||
|
# validated green on the load-pcb chromium-ci spec — but a lighter, faster pass,
|
||||||
|
# which is why CI sets -O1). -O2 stays the default for the more thorough rewrite.
|
||||||
|
# Do NOT use -Os/-Oz here: they break the asyncify runtime (Binaryen #4484).
|
||||||
|
BINARYEN_OPT_LEVEL="${BINARYEN_OPT_LEVEL:--O2}"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Running wasm-opt -O2 on the asyncified wasm..."
|
echo "Running wasm-opt ${BINARYEN_OPT_LEVEL} on the asyncified wasm..."
|
||||||
echo " Purpose: shrink asyncify-instrumented functions back under V8's"
|
echo " Purpose: shrink asyncify-instrumented functions back under V8's"
|
||||||
echo " per-function locals limit (otherwise large coroutine-entry and"
|
echo " per-function locals limit (otherwise large coroutine-entry and"
|
||||||
echo " similar functions silently stall in Chrome's V8). See docs/debugging/DEBUG.md §7"
|
echo " similar functions stall/crash in Chrome's V8). See docs/debugging/DEBUG.md §6-7."
|
||||||
echo " and memory/bundle-size-asyncify-optimization.md."
|
echo " This pass takes several minutes and ~10-15 GB RAM."
|
||||||
echo " This pass also takes several minutes and ~10-15 GB RAM."
|
|
||||||
echo " BINARYEN_CORES=${BINARYEN_CORES}"
|
echo " BINARYEN_CORES=${BINARYEN_CORES}"
|
||||||
echo " LD_PRELOAD=${WASM_OPT_PRELOAD:-<none>}"
|
echo " LD_PRELOAD=${WASM_OPT_PRELOAD:-<none>}"
|
||||||
|
|
||||||
"${PRELOAD_CMD[@]}" "${TIME_CMD[@]}" "${WASM_OPT}" -O2 "${OUTPUT_WASM}" -o "${OUTPUT_WASM}"
|
"${PRELOAD_CMD[@]}" "${TIME_CMD[@]}" "${WASM_OPT}" "${BINARYEN_OPT_LEVEL}" "${OUTPUT_WASM}" -o "${OUTPUT_WASM}"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Asyncify + -O2 complete: ${OUTPUT_WASM}"
|
echo "Asyncify + ${BINARYEN_OPT_LEVEL} complete: ${OUTPUT_WASM}"
|
||||||
ls -lh "${OUTPUT_WASM}"
|
ls -lh "${OUTPUT_WASM}"
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,10 @@ export default defineConfig({
|
||||||
// as playwright.config.ts): the load-pcb post-load clipboard crash that can
|
// as playwright.config.ts): the load-pcb post-load clipboard crash that can
|
||||||
// close the page on Firefox, and the calculator first-run-wizard timing race.
|
// close the page on Firefox, and the calculator first-run-wizard timing race.
|
||||||
retries: process.env.CI ? 2 : 1,
|
retries: process.env.CI ? 2 : 1,
|
||||||
workers: process.env.CI ? 1 : undefined,
|
// Run parallel workers on CI too (Playwright default ≈ 50% of cores), same as
|
||||||
|
// local — the serial CI run was the dominant wall-clock cost. Cap (e.g. '50%'
|
||||||
|
// or a fixed count) if contention OOMs/flakes; retries:2 covers transient.
|
||||||
|
workers: undefined,
|
||||||
reporter: 'html',
|
reporter: 'html',
|
||||||
timeout: 180000, // KiCad WASM needs more time to load (3 minutes)
|
timeout: 180000, // KiCad WASM needs more time to load (3 minutes)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,10 @@ export default defineConfig({
|
||||||
// 1 local retry absorbs transient `npx serve` connection refusals under heavy
|
// 1 local retry absorbs transient `npx serve` connection refusals under heavy
|
||||||
// parallel load (many workers fetching large WASM bundles at once).
|
// parallel load (many workers fetching large WASM bundles at once).
|
||||||
retries: process.env.CI ? 2 : 1,
|
retries: process.env.CI ? 2 : 1,
|
||||||
workers: process.env.CI ? 1 : undefined,
|
// Run parallel workers on CI too (Playwright default ≈ 50% of cores), same as
|
||||||
|
// local — the serial CI run was the dominant wall-clock cost. Cap (e.g. '50%'
|
||||||
|
// or a fixed count) if contention OOMs/flakes; retries:2 covers transient.
|
||||||
|
workers: undefined,
|
||||||
reporter: 'html',
|
reporter: 'html',
|
||||||
timeout: 60000, // WASM can be slow to load
|
timeout: 60000, // WASM can be slow to load
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue