Skip to content

Performance (nightly) #9

Performance (nightly)

Performance (nightly) #9

Workflow file for this run

name: Performance (nightly)
# NOT on pull_request, and that is the point.
#
# The metrics here are durations and memory. macos-14 is a 3-core virtualised
# runner and Apple's Virtualization Framework does not expose Metal Performance
# Shaders to the guest, so the spread between two runs of identical code is
# wider than most regressions we would want to catch. Gating a merge on that
# would fail honest PRs and teach everyone to re-run until green.
#
# What DOES gate a PR lives in the normal test job: counts and static facts,
# which are machine-independent (src/store/selectorFanout.test.ts is the worked
# example). The full argument, including why Orca can gate its nightly and we
# cannot, is in docs/perf-ci.md.
#
# So this job reports. It writes a step summary you can read without
# downloading anything, and uploads the JSON so a series can be assembled
# later. A metric earns a threshold only after its real spread is known.
on:
workflow_dispatch:
inputs:
ref:
description: Ref to check out (defaults to the workflow ref)
required: false
type: string
memory_cycles:
description: View-churn cycles for the memory spec (default 12)
required: false
type: string
grep:
description: Mocha grep, to run one spec while chasing a regression
required: false
type: string
schedule:
# 03:30 UTC. Off the PR path entirely; nothing waits on this.
- cron: '30 3 * * *'
# A slow nightly must never pile up behind itself.
concurrency:
group: perf-${{ github.ref }}
cancel-in-progress: true
jobs:
perf:
name: startup + memory (macos-14)
# Cron is upstream-only, so forks stop getting nightly failure mail.
# Manual dispatch stays open everywhere.
if: github.event_name == 'workflow_dispatch' || github.repository == 'simion/termic'
runs-on: macos-14
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.ref || github.ref }}
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri
- run: npm ci
- name: Seed fixture profile
run: node scripts/e2e-seed.mjs
- name: Build perf binary
run: npm run perf:build
- name: Run perf suite
env:
TERMIC_PERF_CYCLES: ${{ inputs.memory_cycles }}
TERMIC_PERF_GREP: ${{ inputs.grep }}
run: |
set -euo pipefail
# Two branches rather than building an argv array. macOS runners ship
# bash 3.2, where `"${arr[@]}"` on an EMPTY array is an UNSET
# expansion, so `set -u` killed the step before it ran a single spec.
# Every scheduled run failed that way from the day this landed, while
# a manual run WITH a grep passed, which is why it went unnoticed.
if [ -n "${TERMIC_PERF_GREP:-}" ]; then
npm run test:perf -- --mochaOpts.grep "$TERMIC_PERF_GREP"
else
npm run test:perf
fi
- name: Upload perf report
# always(): a partial report from a run that lost one spec is still a
# data point, and the WebGL renderer fact in particular is worth having
# even when a later spec fell over.
if: always()
uses: actions/upload-artifact@v4
with:
name: perf-report
path: .perf/
retention-days: 90
if-no-files-found: warn
# `.perf/` is a DOT directory and upload-artifact treats hidden paths
# as excluded, so the step uploaded nothing while the suite happily
# reported "wrote 10 rows" beside it. `if-no-files-found: warn` is a
# warning nobody reads on a green job.
include-hidden-files: true