name: Run the performance journeys description: >- Runs `pnpm run perf:journeys` under xvfb on an Ubuntu runner, writes the measurements to the job summary and returns the path of the summary.json it wrote. Callers check out, set up pnpm and Node, install dependencies and upload what they need. Contract: docs/architecture/performance-journeys.md. outputs: summary: description: Path of the journey summary.json this run wrote. value: ${{ steps.summary.outputs.path }} runs: using: composite steps: # The journeys drive Electron through Playwright's _electron API # and never launch a Playwright browser, so no `playwright # install`. The runner image ships Electron's shared libraries and # xvfb; fail fast with a clear message if an image update drops one. # pnpm skips Electron's postinstall, so download the binary first; # otherwise ldd sees no file and the check passes vacuously. - name: Check Electron runtime dependencies shell: bash run: | command -v xvfb-run || { echo "::error::xvfb-run is missing on the runner"; exit 1; } node tools/testing/ensure-electron-binary.mjs || { echo "::error::Electron binary download failed"; exit 1; } missing="$(ldd node_modules/electron/dist/electron | grep 'not found' || true)" if [ -n "$missing" ]; then echo "::error::Electron is missing shared libraries:" echo "$missing" exit 1 fi # The Nx target builds electron-backend:build-performance first # and playwright.journeys.config.ts starts the Xtream mock server. - name: Run the performance journeys shell: bash run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" pnpm run perf:journeys env: CI: 'true' NX_TASKS_RUNNER_DYNAMIC_OUTPUT: 'false' # Every run writes a fresh timestamped directory, so a clean # checkout must hold exactly one summary. - name: Locate the journey summary id: summary shell: bash run: | set -euo pipefail mapfile -t summaries < <(find dist/performance/journeys -mindepth 2 -maxdepth 2 -name summary.json) if [ "${#summaries[@]}" -ne 1 ]; then echo "::error::Expected one journey summary, found ${#summaries[@]}" exit 1 fi echo "path=${summaries[0]}" >> "$GITHUB_OUTPUT" - name: Report journey measurements shell: bash env: SUMMARY: ${{ steps.summary.outputs.path }} run: | set -euo pipefail jq -r ' "## Performance journeys (\(.harness.platform), \(.harness.measuredIterations) measured iterations)", "", (.journeys | to_entries[] | .key as $journey | .value as $j | "### `\($journey)`", "", "| Measurement | Value | Iterations |", "| --- | ---: | --- |", (($j.counters // {}) | to_entries[] | ($j.counterStability[.key] // {}) as $s | "| `\(.key)` | \(.value) | \(($s.values // []) | map(tostring) | join(", "))\(if $s.stable == false then " (unstable)" else "" end) |"), (($j.wallClock // {}) | to_entries[] | "| `\(.key)` | \(.value) | |"), "", ([($j.iterations // [])[] | select(.warmup | not) | .evidence.ipcSerialDepth // empty][0] // empty | "Serial IPC chain (first measured iteration): \(.chain | map("`\(.)`") | join(" → "))", "")) ' "$SUMMARY" | tee -a "$GITHUB_STEP_SUMMARY"