Skip to content

Bug: Defer Disconnect Teardown #482

Bug: Defer Disconnect Teardown

Bug: Defer Disconnect Teardown #482

Workflow file for this run

name: Benchmarks
on:
pull_request:
paths:
# perf-sensitive code — the measurement target
- 'packages/**'
# bench workflow itself — changes here take effect on this PR's own
# run (pull_request uses PR-head YAML), so self-test
- '.github/workflows/benchmarks.yml'
# Bench source (bench-*.js, tachometer-ci*.json, build-ci.js) and
# reporter (tools/ci/bench/reporter/**) are deliberately NOT listed here.
# The discover and benchmarks jobs overlay main's copy of both before
# every run, so PR-side edits have no effect on the PR's own comment.
# Harness changes land on main in a separate PR; test-taker cannot
# author the test.
# Bench every merge commit on main so bench-history.json accumulates
# absolute CIs per commit. These runs aren't gated against anything —
# the report workflow branches on event type and appends history instead
# of posting a PR comment.
push:
branches: [main]
paths:
- 'packages/**'
concurrency:
group: bench-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
# Discover which tachometer configs are in changed packages.
# Emits one matrix entry per tachometer-ci*.json so each runs in its own
# parallel job with its own PR check.
discover:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.matrix.outputs.result }}
has-benchmarks: ${{ steps.matrix.outputs.has-benchmarks }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: actions/setup-node@v6
with:
node-version-file: '.node-version'
# Pin bench harness to main. Matrix composition (tools/ci/bench/matrix,
# bench source, tachometer configs, reporter) is author-neutral —
# test-taker can't widen or narrow its own scope, rewrite discover.js,
# or add a rigged config. Harness changes land on main first.
- name: Overlay bench harness from main
run: |
git fetch origin main --depth=1
git checkout origin/main -- packages/*/bench/ tools/ci/bench/reporter/ tools/ci/bench/matrix/ 2>/dev/null || true
# Collect the PR's changed-file set vs base; discover.js filters the
# matrix to configs whose owning package's @semantic-ui/* dep closure
# intersects the diff. Push to main writes an empty file — discover.js
# falls through to "run everything" for bench-history continuity.
- name: Collect changed files
run: |
if [ '${{ github.event_name }}' = 'pull_request' ]; then
git fetch origin ${{ github.event.pull_request.base.ref }} --depth=1
git diff --name-only FETCH_HEAD...HEAD > /tmp/changed-files.txt
else
: > /tmp/changed-files.txt
fi
echo 'Changed files:'
cat /tmp/changed-files.txt
- name: Build matrix
id: matrix
env:
CHANGED_FILES_PATH: /tmp/changed-files.txt
run: node tools/ci/bench/matrix/discover.js
benchmarks:
needs: discover
if: needs.discover.outputs.has-benchmarks == 'true'
strategy:
fail-fast: false
matrix:
entry: ${{ fromJson(needs.discover.outputs.matrix) }}
name: bench-${{ matrix.entry.name }}
runs-on: ubuntu-latest
# With amplified metrics (Bench: Amplify… commits), a typical run lands
# at 12-14 min — initial sampling dominates, ~9 min at N=50 × 2 benches ×
# N metrics, then auto-sample usually converges in 2-3 min. 25-min cap
# gives margin over the observed ceiling; the 9-metric template cell with
# each-mount-1000 added sits closest to the limit and was cancelling at
# 20 min on the FGR PR.
timeout-minutes: 25
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version-file: '.node-version'
cache: 'npm'
cache-dependency-path: package-lock.json
- name: Install dependencies
run: npm ci
- name: Install matching chromedriver
run: |
CHROME_VERSION=$(google-chrome --version | grep -oP '\d+' | head -1)
npm install chromedriver@${CHROME_VERSION} --no-save
# Pin bench harness to main for both current and baseline builds.
# The PR only contributes packages/*/src/; bench code, tachometer
# configs, and build-ci.js always come from main so the measurement
# is author-neutral.
- name: Overlay bench harness from main
run: |
git fetch origin main --depth=1
git checkout origin/main -- packages/*/bench/ tools/ci/bench/reporter/ 2>/dev/null || true
# Build current branch benchmark bundles
- name: Build current
run: node packages/${{ matrix.entry.package }}/bench/tachometer/build-ci.js current
# Swap source to the appropriate baseline and build baseline bundles.
# PR: baseline = base branch tip.
# Push to main: baseline = this commit's parent (so the delta captures
# the merged commit's effect; bench-history indexes the current
# commit's absolute CI alongside the within-session percent-delta).
#
# Resolve baseline SHA inline so it can be written to the artifact as
# a sidecar (baseline-sha.txt). The reporter pins each metric's
# percent_delta_ci to that SHA — required for cross-iteration drift
# detection (see tools/ci/bench/reporter/reporter.js:computeBaselineDrift).
- name: Build baseline
run: |
if [ '${{ github.event_name }}' = 'push' ]; then
# Fetch enough history to reach the parent commit locally.
git fetch origin main --depth=2
BASELINE_SHA=$(git rev-parse HEAD~1)
git checkout HEAD~1 -- packages/*/src/
else
git fetch origin ${{ github.event.pull_request.base.ref }} --depth=1
BASELINE_SHA=$(git rev-parse FETCH_HEAD)
git checkout FETCH_HEAD -- packages/*/src/
fi
node packages/${{ matrix.entry.package }}/bench/tachometer/build-ci.js baseline
git checkout HEAD -- packages/*/src/
mkdir -p results
echo "$BASELINE_SHA" > results/baseline-sha.txt
# Run just this matrix cell's single config.
# Per-cell auto-sample tail is governed by the config's own `timeout`
# (tachometer rejects --timeout alongside --config). Hard runaway
# protection is `timeout-minutes: 10` at the job level above.
- name: Run benchmark
run: |
mkdir -p results
npx tachometer \
--config "${{ matrix.entry.config }}" \
--json-file "results/${{ matrix.entry.package }}-${{ matrix.entry.name }}.json"
- name: Upload results
uses: actions/upload-artifact@v7
with:
name: results-${{ matrix.entry.name }}
# Include baseline-sha.txt sidecar — the reporter and history
# archiver read it to pin percent_delta_ci entries to their
# baseline SHA.
path: |
results/*.json
results/baseline-sha.txt