Files
hyperframes/.github/workflows/studio-drag-frames.yml
T
Miguel Ángel 438ea9d59f perf(studio): manual edits stay under 8 ms per frame (#4898)
* ci(studio): measure any edit cases on quiet runners, five runs in parallel

* perf(studio): an undo or save stops re-rendering every panel

* test(studio): the edit bench types one key per frame, as a person does

* fix(studio): the edit bench measures frame work when a task outside the drag has no thread time

* refactor(studio): hooks hand back stable handlers themselves, keeping App.tsx under 600 lines

* test(studio): the edit bench says why a case's frame work is unknown

* fix(studio): the edit bench counts a task without thread time at its wall time

* perf(studio): draw toasts on an opaque surface without backdrop blur

* fix(studio): keep stable handlers bound to the project they were made in

* fix(studio): every stable handler names the project it belongs to

* style(studio): format the stable handler call sites

* refactor(studio): name the timeline editing handler objects before wrapping them
2026-10-02 21:15:19 +00:00

86 lines
3.4 KiB
YAML

name: Studio drag frames
permissions:
contents: read
env:
HYPERFRAMES_NO_TELEMETRY: "1"
# Measures drag smoothness on a runner with nothing else on it. The bench measures a blank page per case
# in the same run, and the box only counts as quiet if that control dropped no frame anywhere.
on:
workflow_dispatch:
inputs:
ref:
description: Commit, branch or tag to measure
default: main
filter:
description: Case ids to run (a regular expression)
default: "^(move|resize|rotate|crop)-(none|tween)-px-r0-root-z100$"
grid:
description: The grid the ids come from (pr or full)
default: pr
pull_request:
paths:
- ".github/workflows/studio-drag-frames.yml"
jobs:
drag-frames:
name: "Studio: drag frames (run ${{ matrix.run }})"
runs-on: ubuntu-latest
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
run: [1, 2, 3, 4, 5]
env:
BENCH_REF: ${{ inputs.ref || 'main' }}
BENCH_FILTER: ${{ inputs.filter || '^(move|resize|rotate|crop)-(none|tween)-px-r0-root-z100$' }}
BENCH_GRID: ${{ inputs.grid || 'pr' }}
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
ref: ${{ env.BENCH_REF }}
lfs: true
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 22
- run: corepack enable
- run: corepack prepare pnpm@10.17.1 --activate
- uses: ./.github/actions/prepare-ffmpeg-bin
- run: bash scripts/ci/install-workspace-dependencies.sh
- run: bun run build
- run: node packages/cli/dist/cli.js browser ensure
- name: Run the drag cases
working-directory: packages/studio
run: |
set -euo pipefail
echo "Measuring $(git rev-parse HEAD)"
bun tests/e2e/edit-accuracy/run.mjs --grid "$BENCH_GRID" --filter "$BENCH_FILTER" \
--jobs 1 --port 5961 --cli "$GITHUB_WORKSPACE/packages/cli/dist/cli.js" \
--out "$RUNNER_TEMP/drag-frames/run-${{ matrix.run }}"
- name: Require a quiet box (the blank page dropped no frame)
run: |
# shellcheck disable=SC2016 # the backticks are JavaScript template strings
node -e '
const fs = require("fs"), dir = process.env.RUNNER_TEMP + "/drag-frames";
let noisy = 0;
for (const run of fs.readdirSync(dir)) {
const { cases } = JSON.parse(fs.readFileSync(`${dir}/${run}/results.json`, "utf8"));
for (const c of cases) {
const dropped = c.smooth?.control?.dropped;
if (dropped !== 0) { noisy++; console.log(`${run} ${c.id} control dropped=${dropped}`); }
}
}
if (noisy) { console.log(`::error::the blank page dropped frames, or went unmeasured, in ${noisy} case(s); this box is not quiet`); process.exit(1); }
console.log("the blank page dropped 0 frames in every case of every run");
'
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
if: always()
with:
name: studio-drag-frames-${{ matrix.run }}
path: ${{ runner.temp }}/drag-frames
if-no-files-found: error
retention-days: 30