Repository navigation
perf(gpui): precompute preset preview geometry, filter matrices, and column tables #221
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Verify recording (real capture) | |
| # Records a marker stimulus through Cap's real Studio and Instant pipelines | |
| # (ScreenCaptureKit + VideoToolbox) on macOS runners and checks every frame | |
| # and audio marker against the host-clock truth. See | |
| # crates/verify/tests/recording.rs. | |
| # | |
| # Every pull request gets a "Verify recording" verdict (the job to require): | |
| # - Scope decides from the diff whether the change reaches the recorder's or | |
| # the stimulus's dependency closure or the harness (scripts/verify/plan.py | |
| # recording); a pull request that does not is green without running; | |
| # - one that does runs the FAST tier on Blacksmith macOS 26, or, once it is | |
| # ready for review (not a draft), the FULL tier there when it touches a | |
| # high-risk region or an engine crate. Blacksmith macOS 15 runs nightly | |
| # only: its Instant recordings with system audio lose a microphone marker | |
| # in every run (on main too), which is under investigation; nightly runs FULL on Blacksmith and GitHub-hosted macOS 15 | |
| # and 26, dispatch FULL on the chosen runners. | |
| # | |
| # Runners: Blacksmith macOS (M4 Pro VM, 6 vCPU, no concurrency cap) for pull | |
| # requests, pushes and dispatch: jobs start at once and every run gets the | |
| # same machine. Blacksmith VMs have no VideoToolbox hardware H.264 encoder | |
| # (VTCompressionSessionCreate with RequireHardwareAcceleratedVideoEncoder | |
| # returns -12903, probe run 38847791287), so recordings there take the | |
| # software (libx264) path; the nightly run adds GitHub-hosted macOS 15 and | |
| # 26, which record through the hardware encoder real Macs use (dispatch | |
| # runners=hosted or both for the same). Blacksmith needs Screen Recording and | |
| # Microphone granted in TCC, its display woken, and an audio device | |
| # (BlackHole), which the setup step below does. | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| repeat: | |
| description: "Runs of each case" | |
| default: "1" | |
| tier: | |
| description: "fast or full" | |
| default: "full" | |
| case_filter: | |
| description: "Case globs, comma-separated (empty runs all)" | |
| default: "" | |
| keep_artifacts: | |
| description: "Preserve recordings and raw crash snapshots for passing cases" | |
| type: boolean | |
| default: false | |
| system_audio: | |
| description: "Blacksmith only: play and require system audio through BlackHole (not yet characterised)" | |
| type: boolean | |
| default: false | |
| runners: | |
| description: "blacksmith (default, software encoder path), hosted (VideoToolbox hardware encoder) or both" | |
| type: choice | |
| options: [blacksmith, hosted, both] | |
| default: blacksmith | |
| schedule: | |
| - cron: "41 3 * * *" | |
| pull_request: | |
| types: [opened, synchronize, reopened, ready_for_review] | |
| push: | |
| branches: | |
| - ci/verify-ci | |
| - ci/verify-recording | |
| concurrency: | |
| group: verify-recording-${{ github.event.pull_request.number || github.ref_name }}-${{ github.event_name }}${{ github.event_name == 'workflow_dispatch' && format('-{0}', github.run_id) || '' }} | |
| cancel-in-progress: ${{ github.event_name != 'schedule' }} | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| jobs: | |
| scope: | |
| name: Scope | |
| runs-on: blacksmith-8vcpu-ubuntu-2404 | |
| timeout-minutes: 5 | |
| outputs: | |
| run: ${{ steps.scope.outputs.run }} | |
| runners: ${{ steps.scope.outputs.runners }} | |
| tier: ${{ steps.scope.outputs.tier }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| persist-credentials: false | |
| - name: Scope | |
| id: scope | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| EVENT: ${{ github.event_name }} | |
| PR: ${{ github.event.pull_request.number }} | |
| DRAFT: ${{ github.event.pull_request.draft }} | |
| BEFORE: ${{ github.event.before }} | |
| INPUT_TIER: ${{ inputs.tier }} | |
| INPUT_RUNNERS: ${{ inputs.runners }} | |
| RUSTUP_TOOLCHAIN: stable | |
| run: | | |
| set -euo pipefail | |
| files="$RUNNER_TEMP/changed.txt" | |
| hosted='["macos-15","macos-26"]' | |
| blacksmith='["blacksmith-6vcpu-macos-15","blacksmith-6vcpu-macos-26"]' | |
| both='["blacksmith-6vcpu-macos-15","blacksmith-6vcpu-macos-26","macos-15","macos-26"]' | |
| case "$EVENT" in | |
| schedule) run=true; runners="$both"; tier=full ;; | |
| workflow_dispatch) | |
| run=true | |
| tier="${INPUT_TIER:-full}" | |
| case "${INPUT_RUNNERS:-blacksmith}" in | |
| hosted) runners="$hosted" ;; | |
| both) runners="$both" ;; | |
| *) runners="$blacksmith" ;; | |
| esac ;; | |
| *) | |
| if [[ "$EVENT" == pull_request ]]; then | |
| gh api "repos/$GITHUB_REPOSITORY/pulls/$PR/files" --paginate --jq '.[].filename' > "$files" | |
| max=3000 | |
| elif [[ "$BEFORE" =~ ^0+$ ]]; then | |
| : > "$files"; echo Cargo.toml >> "$files" | |
| max=300 | |
| else | |
| gh api "repos/$GITHUB_REPOSITORY/compare/$BEFORE...$GITHUB_SHA" --jq '.files[].filename' > "$files" | |
| max=300 | |
| fi | |
| python3 scripts/verify/plan.py recording --files "$files" --max-files "$max" > "$RUNNER_TEMP/scope.txt" | |
| cat "$RUNNER_TEMP/scope.txt" | |
| run="$(sed -n 's/^run=//p' "$RUNNER_TEMP/scope.txt")" | |
| python3 scripts/verify/plan.py risk --files "$files" --summary "$GITHUB_STEP_SUMMARY" --output "$RUNNER_TEMP/risk.txt" | |
| if [[ "${DRAFT:-false}" != true ]] && { grep -qx 'escalate=true' "$RUNNER_TEMP/risk.txt" || grep -qx 'engine=true' "$RUNNER_TEMP/risk.txt"; }; then | |
| runners='["blacksmith-6vcpu-macos-26"]'; tier=full | |
| else | |
| runners='["blacksmith-6vcpu-macos-26"]'; tier=fast | |
| fi ;; | |
| esac | |
| { | |
| echo "run=$run" | |
| echo "runners=$runners" | |
| echo "tier=$tier" | |
| } >> "$GITHUB_OUTPUT" | |
| if [[ "$run" == true ]]; then | |
| echo "real capture: $tier tier on $runners" | tee -a "$GITHUB_STEP_SUMMARY" | |
| else | |
| echo "real capture: no recording code changed, nothing to run" | tee -a "$GITHUB_STEP_SUMMARY" | |
| fi | |
| real-capture: | |
| needs: scope | |
| if: needs.scope.outputs.run == 'true' | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| runner: ${{ fromJSON(needs.scope.outputs.runners) }} | |
| runs-on: ${{ matrix.runner }} | |
| timeout-minutes: 45 | |
| env: | |
| CAP_VERIFY_CAPTURE: display | |
| CAP_VERIFY_REQUIRE_CAPTURE: "1" | |
| CAP_VERIFY_TIER: ${{ needs.scope.outputs.tier }} | |
| CAP_VERIFY_REPEAT: ${{ inputs.repeat || (github.event_name == 'schedule' && '3') || '1' }} | |
| CAP_VERIFY_CASE: ${{ inputs.case_filter || '' }} | |
| CAP_VERIFY_KEEP: ${{ inputs.keep_artifacts && '1' || '' }} | |
| CAP_VERIFY_SCRATCH: ${{ github.workspace }}/verify-scratch | |
| CAP_VERIFY_REPORT_DIR: ${{ github.workspace }}/verify-report | |
| CAP_VERIFY_DUMP: ${{ github.workspace }}/verify-dump | |
| CAP_VERIFY_HOST: ${{ startsWith(matrix.runner, 'blacksmith-') && 'blacksmith' || 'github-hosted' }} | |
| # A case this runner cannot run fails, except system audio as the only | |
| # audio while the stimulus stays silent (see below). | |
| CAP_VERIFY_REQUIRE_SUPPORTED: "1" | |
| CAP_VERIFY_UNSUPPORTED_ALLOW: ${{ !(startsWith(matrix.runner, 'blacksmith-') && inputs.system_audio) && 'recording/instant/system-only' || '' }} | |
| # Hosted runners' output devices give ScreenCaptureKit only silence, so | |
| # system audio is not checked there. Blacksmith gets BlackHole (set up | |
| # below), which does carry the stimulus's audio on macOS 15 (not on | |
| # 26), but its system-audio timing is not characterised yet (run | |
| # 38843005408: system audio +31 to +44 ms against the mic, BlackHole | |
| # latency not in the truth), so by default the stimulus stays silent | |
| # there too; dispatch system_audio=true plays and requires it. | |
| CAP_VERIFY_AUDIO_OUTPUT: ${{ startsWith(matrix.runner, 'blacksmith-') && 'BlackHole 2ch' || matrix.runner == 'macos-26' && 'Null Audio Device' || '' }} | |
| CAP_VERIFY_STIMULUS_AUDIO: ${{ startsWith(matrix.runner, 'blacksmith-') && !inputs.system_audio && '0' || '' }} | |
| CAP_VERIFY_REQUIRE_SYSTEM_AUDIO: ${{ startsWith(matrix.runner, 'blacksmith-') && inputs.system_audio && '1' || '' }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@1.88.0 | |
| - uses: ./.github/actions/setup-rust-cache | |
| with: | |
| target: aarch64-apple-darwin | |
| prefix-key: v1-rust-verify-recording-${{ matrix.runner }} | |
| save-cache: "true" | |
| - uses: ./.github/actions/install-desktop-deps | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 24 | |
| - name: Native dependencies | |
| env: | |
| RUST_TARGET_TRIPLE: aarch64-apple-darwin | |
| run: node scripts/setup.js | |
| - name: Runner devices | |
| run: | | |
| sw_vers | |
| system_profiler SPDisplaysDataType SPAudioDataType 2>/dev/null | sed -n 1,80p | |
| sysctl hw.memsize hw.ncpu | |
| # Spotlight indexes the build and every recording the suite writes: | |
| # mds (priority 50) plus a dozen mdworkers averaged 1 to 1.8 of the 3 | |
| # cores during the tests (ps samples, run 38736744971). | |
| - name: Disable Spotlight indexing | |
| run: | | |
| sudo mdutil -a -i off || true | |
| sudo mdutil -as || true | |
| - name: Build | |
| run: | | |
| start=$(date +%s) | |
| cargo build --locked -p cap-verify-stimulus | |
| cargo test --locked -p cap-verify --test recording --no-run | |
| echo "build seconds: $(( $(date +%s) - start ))" | |
| # Blacksmith runs a logged-in GUI session with SIP disabled, but: | |
| # - ScreenCaptureKit is denied until TCC grants the responsible process | |
| # (Runner.Worker), so Screen Recording and Microphone are granted to | |
| # every binary that captures plus the whole runner ancestry, in the | |
| # system and the user TCC database (Microphone is a per-user | |
| # service: without it CoreAudio blocks the stimulus forever in | |
| # AudioDeviceCreateIOProcID waiting for coreaudiod), then tccd | |
| # restarts; | |
| # - the display starts asleep (CGDisplayIsAsleep, no active display), | |
| # so ScreenCaptureKit lists windows but no display: wake it and keep | |
| # it awake for the job; | |
| # - there is no audio device: BlackHole provides input and output. | |
| - name: Blacksmith capture permissions and audio device | |
| if: startsWith(matrix.runner, 'blacksmith-') | |
| run: | | |
| set -euo pipefail | |
| sudo pmset -a displaysleep 0 sleep 0 disksleep 0 | |
| caffeinate -u -t 2 | |
| nohup caffeinate -dimsu > /dev/null 2>&1 & | |
| brew install --cask blackhole-2ch | |
| brew install switchaudio-osx | |
| sudo killall coreaudiod || true | |
| for _ in $(seq 1 30); do | |
| SwitchAudioSource -a -t output | grep -qx "BlackHole 2ch" && break | |
| sleep 1 | |
| done | |
| SwitchAudioSource -s "BlackHole 2ch" -t output | |
| SwitchAudioSource -s "BlackHole 2ch" -t input | |
| echo "outputs:"; SwitchAudioSource -a -t output | |
| echo "default output: $(SwitchAudioSource -c -t output)" | |
| { cargo build --locked -p cap-verify-stimulus --message-format=json 2>/dev/null; \ | |
| cargo test --locked -p cap-verify --test recording --no-run --message-format=json 2>/dev/null; } \ | |
| | python3 -c 'import json, sys | |
| for line in sys.stdin: | |
| m = json.loads(line) | |
| if m.get("reason") == "compiler-artifact" and m.get("executable") and m["target"]["name"] in ("recording", "cap-verify-stimulus"): | |
| print(m["executable"])' > "$RUNNER_TEMP/capture-binaries" | |
| test "$(wc -l < "$RUNNER_TEMP/capture-binaries")" -ge 2 | |
| p=$$ | |
| while [ "$p" -gt 1 ]; do | |
| ps -o comm= -p "$p" | |
| p=$(ps -o ppid= -p "$p" | tr -d ' ') | |
| done >> "$RUNNER_TEMP/capture-binaries" | |
| for c in "$(rustup which cargo)" "$HOME/.cargo/bin/cargo"; do echo "$c"; done >> "$RUNNER_TEMP/capture-binaries" | |
| db="/Library/Application Support/com.apple.TCC/TCC.db" | |
| user_db="$HOME/Library/Application Support/com.apple.TCC/TCC.db" | |
| approvals="$HOME/Library/Group Containers/group.com.apple.replayd/ScreenCaptureApprovals.plist" | |
| mkdir -p "$(dirname "$approvals")" | |
| now=$(date +%s) | |
| until=$(date -u -v+1y '+%a %b %d %H:%M:%S GMT %Y') | |
| sort -u "$RUNNER_TEMP/capture-binaries" | grep '^/' | while read -r client; do | |
| for service in kTCCServiceScreenCapture kTCCServiceMicrophone; do | |
| row="INSERT OR REPLACE INTO access (service,client,client_type,auth_value,auth_reason,auth_version,indirect_object_identifier,flags,last_modified) VALUES ('$service','$client',1,2,4,1,'UNUSED',0,$now);" | |
| sudo sqlite3 "$db" "$row" | |
| sqlite3 "$user_db" "$row" | |
| done | |
| /usr/libexec/PlistBuddy -c "Add :$client date $until" "$approvals" >/dev/null 2>&1 || true | |
| echo "granted $client" | |
| done | |
| killall tccd || true | |
| sudo killall tccd || true | |
| sleep 2 | |
| cat > "$RUNNER_TEMP/display.swift" <<'SWIFT' | |
| import CoreGraphics | |
| let main = CGMainDisplayID() | |
| print("display \(main): asleep \(CGDisplayIsAsleep(main)), active \(CGDisplayIsActive(main)), \(CGDisplayBounds(main)), screen capture \(CGPreflightScreenCaptureAccess())") | |
| SWIFT | |
| swiftc "$RUNNER_TEMP/display.swift" -o "$RUNNER_TEMP/display" | |
| "$RUNNER_TEMP/display" | |
| - name: Real-capture recording oracle | |
| run: | | |
| mkdir -p "$CAP_VERIFY_DUMP" | |
| # One-second process samples (CPU, scheduler priority) so an | |
| # environment failure can be attributed. | |
| (while sleep 1; do | |
| date -u +%H:%M:%S | |
| ps -A -o pid,pri,%cpu,comm -r | head -14 | |
| for p in $(pgrep -f cap-verify-stimulus | head -1) $(pgrep -f 'deps/recording-' | head -1); do | |
| ps -M -p "$p" | awk 'NR == 1 || $4 > 0.5 || NR < 4' | cut -c1-90 | |
| done | |
| done) > "$CAP_VERIFY_DUMP/ps.log" 2>&1 & | |
| top_pid=$! | |
| start=$(date +%s) | |
| set +e | |
| cargo test --locked -p cap-verify --test recording -- --nocapture | |
| status=$? | |
| set -e | |
| kill "$top_pid" || true | |
| echo "test seconds: $(( $(date +%s) - start ))" | |
| exit "$status" | |
| - name: Summary | |
| if: always() | |
| run: | | |
| python3 scripts/verify/summary.py --title "real capture ${{ matrix.runner }} ${{ needs.scope.outputs.tier }}" "$CAP_VERIFY_REPORT_DIR" >> "$GITHUB_STEP_SUMMARY" || true | |
| - name: Upload artifacts | |
| if: always() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: verify-recording-${{ matrix.runner }} | |
| path: | | |
| ${{ github.workspace }}/verify-report | |
| ${{ github.workspace }}/verify-dump | |
| ${{ github.workspace }}/verify-scratch | |
| if-no-files-found: ignore | |
| # The check to require: green when the change is out of scope or every | |
| # planned runner passed with at least the tier's case count. | |
| gate: | |
| name: Verify recording | |
| needs: [scope, real-capture] | |
| if: always() | |
| runs-on: blacksmith-8vcpu-ubuntu-2404 | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| persist-credentials: false | |
| sparse-checkout: scripts/verify | |
| - uses: actions/download-artifact@v4 | |
| if: needs.scope.outputs.run == 'true' | |
| with: | |
| pattern: verify-recording-* | |
| path: ${{ runner.temp }}/reports | |
| - name: Verdict | |
| env: | |
| SCOPE: ${{ needs.scope.result }} | |
| RUN: ${{ needs.scope.outputs.run }} | |
| CAPTURE: ${{ needs.real-capture.result }} | |
| TIER: ${{ needs.scope.outputs.tier }} | |
| RUNNERS: ${{ needs.scope.outputs.runners }} | |
| CASE_FILTER: ${{ inputs.case_filter }} | |
| run: | | |
| if [[ "$SCOPE" != success ]]; then | |
| echo "scoping failed" >&2 | |
| exit 1 | |
| fi | |
| if [[ "$RUN" != true ]]; then | |
| echo "No recording code changed: nothing to verify." | tee -a "$GITHUB_STEP_SUMMARY" | |
| exit 0 | |
| fi | |
| if [[ "$CAPTURE" != success ]]; then | |
| echo "real capture $CAPTURE ($TIER tier): see the runner jobs" >&2 | |
| exit 1 | |
| fi | |
| if [[ -n "$CASE_FILTER" ]]; then | |
| echo "case filter set: executed-case floor not applied" | |
| exit 0 | |
| fi | |
| floor=0 | |
| python3 scripts/verify/floor.py --recording --tier "$TIER" --runners "$RUNNERS" "$RUNNER_TEMP/reports" > "$RUNNER_TEMP/floor.txt" || floor=$? | |
| cat "$RUNNER_TEMP/floor.txt" | tee -a "$GITHUB_STEP_SUMMARY" | |
| if [[ $floor != 0 ]]; then | |
| echo "::error::fewer real-capture cases ran than planned" | |
| exit 1 | |
| fi |