Skip to content

Fix residual docs metadata from Ahrefs audit #28395

Fix residual docs metadata from Ahrefs audit

Fix residual docs metadata from Ahrefs audit #28395

name: Activation performance
on:
pull_request:
workflow_dispatch:
inputs:
ref:
description: Branch or SHA to test
required: false
default: ""
runner:
description: macOS runner (auto follows MACOS_RUNNER_15, default WarpBuild; pick blacksmith-/depot-* to override)
required: false
default: auto
type: choice
options:
- auto
- blacksmith-6vcpu-macos-15
- blacksmith-6vcpu-macos-26
- blacksmith-6vcpu-macos-latest
- warp-macos-15-arm64-6x
- depot-macos-latest
- depot-macos-14
workspace_count:
description: Fixture workspace count
required: false
default: "12"
heavy_scrollback_lines:
description: Max lines per terminal in the selected heavy workspace before target scaling
required: false
default: "2400"
other_scrollback_lines:
description: Max lines per terminal in other workspaces before target scaling
required: false
default: "1400"
scrollback_target_chars:
description: Target real scrollback chars before the timed snapshot, 0 disables scaling
required: false
default: "1500000"
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
activation_changes:
runs-on: ${{ vars.LINUX_RUNNER || 'blacksmith-4vcpu-ubuntu-2404' }}
timeout-minutes: 5
outputs:
macos: ${{ steps.detect.outputs.macos }}
web: ${{ steps.detect.outputs.web }}
go: ${{ steps.detect.outputs.go }}
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- name: Detect CI change areas
id: detect
env:
EVENT_NAME: ${{ github.event_name }}
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
set -euo pipefail
emit_all_areas() {
echo "macos=true" >> "$GITHUB_OUTPUT"
echo "web=true" >> "$GITHUB_OUTPUT"
echo "go=true" >> "$GITHUB_OUTPUT"
}
if [ "$EVENT_NAME" = "pull_request" ]; then
if ! MERGE_BASE="$(git merge-base "$BASE_SHA" "$HEAD_SHA")" \
|| ! git diff --name-only "$MERGE_BASE" "$HEAD_SHA" > /tmp/cmux-activation-changed-files.txt; then
echo "Could not compute PR diff; running activation benchmark." >&2
emit_all_areas
exit 0
fi
if [ ! -s /tmp/cmux-activation-changed-files.txt ]; then
echo "PR diff is empty; running activation benchmark."
emit_all_areas
exit 0
fi
# This guard runs before the PR-editable Python detector. Workflow
# and detector edits must fail open to the benchmark.
if grep -Eq '^(\.github/workflows/[^/]+\.ya?ml|scripts/ci/[^/]+\.py|tests/test_ci_change_areas\.py)$' /tmp/cmux-activation-changed-files.txt; then
echo "CI router changed; running activation benchmark."
emit_all_areas
exit 0
fi
python3 scripts/ci/detect_ci_change_areas.py \
--event-name "$EVENT_NAME" \
--files-from /tmp/cmux-activation-changed-files.txt
exit 0
fi
python3 scripts/ci/detect_ci_change_areas.py \
--event-name "$EVENT_NAME" \
--base-sha "$BASE_SHA" \
--head-sha "$HEAD_SHA"
activation-session-benchmark:
needs: activation_changes
if: ${{ needs.activation_changes.outputs.macos == 'true' }}
runs-on: ${{ ((!inputs.runner || inputs.runner == 'auto') && (vars.MACOS_RUNNER_15 || 'warp-macos-15-arm64-6x') || inputs.runner) }}
timeout-minutes: 45
env:
PERF_TAG: perf-${{ github.run_id }}-${{ github.run_attempt }}
steps:
- name: Validate Depot runner identity
if: ${{ startsWith(((!inputs.runner || inputs.runner == 'auto') && (vars.MACOS_RUNNER_15 || 'warp-macos-15-arm64-6x') || inputs.runner), 'depot-macos-') }}
env:
REQUESTED_RUNNER: ${{ ((!inputs.runner || inputs.runner == 'auto') && (vars.MACOS_RUNNER_15 || 'warp-macos-15-arm64-6x') || inputs.runner) }}
RUNNER_CONTEXT_NAME: ${{ runner.name }}
run: |
set -euo pipefail
echo "Requested runner: $REQUESTED_RUNNER"
case "$RUNNER_CONTEXT_NAME" in
depot-*)
echo "Resolved runner matches depot-*? yes"
;;
*)
echo "Resolved runner matches depot-*? no"
echo "::error::$REQUESTED_RUNNER resolved outside Depot. Remove $REQUESTED_RUNNER from non-Depot self-hosted runners or choose an explicit runner."
exit 1
;;
esac
- name: Clear stale git locks (self-hosted reused workspace)
shell: bash
run: |
# Self-hosted macOS runners reuse the workspace. A job cancelled or
# killed mid-checkout can leave a stale .git/modules/*/index.lock that
# fails every later submodule checkout (e.g. ghostty). Clear them first.
ws="${GITHUB_WORKSPACE:-$PWD}"
rm -f "$ws/.git/index.lock" 2>/dev/null || true
if [ -d "$ws/.git/modules" ]; then
find "$ws/.git/modules" -type f -name "*.lock" -delete 2>/dev/null || true
fi
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
ref: ${{ inputs.ref || github.ref }}
submodules: recursive
- name: Select Xcode
run: |
set -euo pipefail
./scripts/select-ci-xcode.sh
- name: Download pre-built GhosttyKit.xcframework
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./scripts/download-prebuilt-ghosttykit.sh
- name: Install zig
env:
HOMEBREW_NO_AUTO_UPDATE: "1"
HOMEBREW_NO_INSTALL_CLEANUP: "1"
HOMEBREW_NO_ENV_HINTS: "1"
run: |
./scripts/install-zig-ci.sh
- name: Install Rust
run: |
./scripts/install-rust-ci.sh
- name: Cache Swift packages
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: .ci-source-packages
key: spm-${{ ((!inputs.runner || inputs.runner == 'auto') && (vars.MACOS_RUNNER_15 || 'warp-macos-15-arm64-6x') || inputs.runner) }}-${{ hashFiles('cmux.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved') }}
restore-keys: spm-${{ ((!inputs.runner || inputs.runner == 'auto') && (vars.MACOS_RUNNER_15 || 'warp-macos-15-arm64-6x') || inputs.runner) }}-
- name: Sanitize Swift package cache
run: python3 scripts/ci/sanitize-xcode-source-packages-cache.py .ci-source-packages
- name: Resolve Swift packages
run: |
set -euo pipefail
SOURCE_PACKAGES_DIR="$PWD/.ci-source-packages"
mkdir -p "$SOURCE_PACKAGES_DIR"
for attempt in 1 2 3; do
if xcodebuild -project cmux.xcodeproj -scheme cmux -configuration Debug \
-clonedSourcePackagesDirPath "$SOURCE_PACKAGES_DIR" \
-resolvePackageDependencies; then
exit 0
fi
if [ "$attempt" -eq 3 ]; then
echo "Failed to resolve Swift packages after 3 attempts" >&2
exit 1
fi
echo "Package resolution failed on attempt $attempt, retrying..."
sleep $((attempt * 5))
done
- name: Build tagged app
run: |
set -euo pipefail
CMUX_SKIP_ZIG_BUILD=1 \
CMUX_SOURCE_PACKAGES_DIR="$PWD/.ci-source-packages" \
CMUX_DISABLE_AUTOMATIC_PACKAGE_RESOLUTION=1 \
./scripts/reload.sh --tag "$PERF_TAG"
- name: Run activation session benchmark
env:
WORKSPACE_COUNT_INPUT: ${{ inputs.workspace_count || '12' }}
HEAVY_SCROLLBACK_LINES_INPUT: ${{ inputs.heavy_scrollback_lines || '2400' }}
OTHER_SCROLLBACK_LINES_INPUT: ${{ inputs.other_scrollback_lines || '1400' }}
SCROLLBACK_TARGET_CHARS_INPUT: ${{ inputs.scrollback_target_chars || '1500000' }}
run: |
set -euo pipefail
validate_non_negative_integer() {
local name="$1"
local value="$2"
case "$value" in
''|*[!0-9]*)
echo "Invalid $name: must be a non-negative integer" >&2
exit 1
;;
esac
}
validate_non_negative_integer workspace_count "$WORKSPACE_COUNT_INPUT"
validate_non_negative_integer heavy_scrollback_lines "$HEAVY_SCROLLBACK_LINES_INPUT"
validate_non_negative_integer other_scrollback_lines "$OTHER_SCROLLBACK_LINES_INPUT"
validate_non_negative_integer scrollback_target_chars "$SCROLLBACK_TARGET_CHARS_INPUT"
RESULTS_DIR="$PWD/perf-results"
mkdir -p "$RESULTS_DIR"
chmod 0777 "$RESULTS_DIR"
APP_PATH="$HOME/Library/Developer/Xcode/DerivedData/cmux-$PERF_TAG/Build/Products/Debug/cmux DEV $PERF_TAG.app"
BENCHMARK_CMD=(
python3 scripts/perf-activation-session.py
--tag "$PERF_TAG"
--app-path "$APP_PATH"
--workspace-count "$WORKSPACE_COUNT_INPUT"
--heavy-scrollback-lines "$HEAVY_SCROLLBACK_LINES_INPUT"
--other-scrollback-lines "$OTHER_SCROLLBACK_LINES_INPUT"
--scrollback-target-chars "$SCROLLBACK_TARGET_CHARS_INPUT"
--synthetic-scrollback-fallback
--output "$RESULTS_DIR/activation-session.json"
--junit "$RESULTS_DIR/activation-session.junit.xml"
)
CONSOLE_USER="$(stat -f %Su /dev/console 2>/dev/null || true)"
if [ -n "$CONSOLE_USER" ] && [ "$CONSOLE_USER" != "root" ] && CONSOLE_UID="$(id -u "$CONSOLE_USER" 2>/dev/null)" && sudo -n true 2>/dev/null; then
CONSOLE_HOME="$( (dscl . -read "/Users/$CONSOLE_USER" NFSHomeDirectory 2>/dev/null || true) | awk '{print $2}')"
if [ -z "$CONSOLE_HOME" ]; then
CONSOLE_HOME="$HOME"
fi
sudo -n launchctl asuser "$CONSOLE_UID" sudo -n -u "$CONSOLE_USER" -E \
env PATH="$PATH" DEVELOPER_DIR="${DEVELOPER_DIR:-}" HOME="$CONSOLE_HOME" GITHUB_WORKSPACE="$PWD" \
bash -c 'cd "$GITHUB_WORKSPACE" && "$@"' bash "${BENCHMARK_CMD[@]}"
else
echo "::warning::Passwordless sudo unavailable; running activation benchmark in current bootstrap" >&2
"${BENCHMARK_CMD[@]}"
fi
- name: Run Cmd-Tab activation benchmark
run: |
set -euo pipefail
APP_PATH="$HOME/Library/Developer/Xcode/DerivedData/cmux-$PERF_TAG/Build/Products/Debug/cmux DEV $PERF_TAG.app"
BUNDLE_ID="$(/usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' "$APP_PATH/Contents/Info.plist")"
# Prefer the console user's Aqua bootstrap when passwordless sudo is
# available. Some self-hosted runners deliberately omit sudo; on
# those, run in the current bootstrap and let the benchmark fail if it
# cannot produce a real CG-visible app window.
CONSOLE_USER="$(stat -f %Su /dev/console 2>/dev/null || true)"
if [ -n "$CONSOLE_USER" ] && [ "$CONSOLE_USER" != "root" ] && CONSOLE_UID="$(id -u "$CONSOLE_USER" 2>/dev/null)" && sudo -n true 2>/dev/null; then
sudo -n launchctl asuser "$CONSOLE_UID" sudo -n -u "$CONSOLE_USER" -E \
env PATH="$PATH" DEVELOPER_DIR="$DEVELOPER_DIR" APP_PATH="$APP_PATH" BUNDLE_ID="$BUNDLE_ID" GITHUB_WORKSPACE="$PWD" \
bash -c 'cd "$GITHUB_WORKSPACE" && swift scripts/bench-window-visibility.swift "$APP_PATH" "$BUNDLE_ID" 30 --cmd-tab-activation --cg-visibility' \
> perf-results/cmd-tab-activation.txt
else
echo "::warning::Passwordless sudo unavailable; running Cmd-Tab benchmark in current bootstrap" >&2
swift scripts/bench-window-visibility.swift "$APP_PATH" "$BUNDLE_ID" 30 --cmd-tab-activation --cg-visibility \
> perf-results/cmd-tab-activation.txt
fi
cat perf-results/cmd-tab-activation.txt
- name: Write benchmark summary
if: always()
run: |
set -euo pipefail
if [ ! -f perf-results/activation-session.json ]; then
echo "No benchmark results were written." >> "$GITHUB_STEP_SUMMARY"
exit 0
fi
python3 - <<'PY' >> "$GITHUB_STEP_SUMMARY"
import json
from pathlib import Path
result = json.loads(Path("perf-results/activation-session.json").read_text())
measurements = result.get("measurements", {})
fixture = result.get("fixture", {})
no_scroll = measurements.get("snapshot_no_scrollback", {})
real_scroll = measurements.get("snapshot_with_real_scrollback", {})
with_scroll = measurements.get("snapshot_with_scrollback", {})
print("## Activation Session Performance")
print("")
print(f"- Fixture: {fixture.get('workspaces')} workspaces, {fixture.get('terminal_surfaces')} terminals, {fixture.get('scrollback_done')} scrollback-ready terminals")
if real_scroll:
print(f"- Real scrollback snapshot: {real_scroll.get('elapsed_ms')} ms, {real_scroll.get('shape', {}).get('scrollback_chars')} chars")
real_capture = fixture.get("real_scrollback_capture") or {}
if real_capture:
print(f"- Real scrollback capture polling: {real_capture.get('attempts')} attempts over {real_capture.get('wait_ms')} ms at {real_capture.get('refresh_rate_hz')} Hz")
print(f"- Added CI time from capture polling: {real_capture.get('retry_overhead_ms')} ms measured, {int(real_capture.get('timeout_s') or 0)} s worst case")
if fixture.get("scrollback_target_chars") is not None:
print(f"- Scrollback seed target: {fixture.get('scrollback_target_chars')} chars, estimated {fixture.get('scrollback_effective_estimated_chars')} chars after scaling from {fixture.get('scrollback_requested_estimated_chars')}")
synthetic_seed = fixture.get("synthetic_scrollback_fallback")
if synthetic_seed:
print(f"- Synthetic scrollback fallback: {synthetic_seed.get('scrollback_chars')} chars across {synthetic_seed.get('terminals')} terminals ({fixture.get('synthetic_scrollback_fallback_reason')})")
print(f"- Launch socket ready: {measurements.get('launch_socket_ready_ms')} ms")
print(f"- Snapshot without scrollback: {no_scroll.get('elapsed_ms')} ms")
print(f"- Snapshot with scrollback: {with_scroll.get('elapsed_ms')} ms")
print(f"- Scrollback chars captured: {with_scroll.get('shape', {}).get('scrollback_chars')}")
print(f"- Restore socket ready: {measurements.get('restore_socket_ready_ms')} ms")
cmd_tab_path = Path("perf-results/cmd-tab-activation.txt")
if cmd_tab_path.exists():
print("")
print("## Cmd-Tab Activation Performance")
print("")
for line in cmd_tab_path.read_text().splitlines():
if line:
print(f"- `{line}`")
failures = result.get("failures") or []
if failures:
print("")
print("### Budget Failures")
for failure in failures:
print(f"- {failure}")
PY
- name: Upload benchmark results
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: activation-session-performance
path: perf-results/
if-no-files-found: ignore
- name: Cleanup tagged app
if: always()
run: |
pkill -f "cmux DEV ${PERF_TAG}.app/Contents/MacOS/cmux DEV" || true
rm -f "/tmp/cmux-debug-${PERF_TAG}.sock"
activation-session:
needs:
- activation_changes
- activation-session-benchmark
if: ${{ always() }}
runs-on: ${{ vars.LINUX_RUNNER || 'blacksmith-4vcpu-ubuntu-2404' }}
timeout-minutes: 5
steps:
- name: Check activation benchmark routing
env:
ACTIVATION_NEEDS: ${{ toJSON(needs) }}
run: |
python3 - <<'PY'
import json
import os
import sys
needs = json.loads(os.environ["ACTIVATION_NEEDS"])
changes = needs["activation_changes"]
benchmark = needs["activation-session-benchmark"]
macos = changes.get("outputs", {}).get("macos")
if changes["result"] != "success":
print(f"changes: {changes['result']}", file=sys.stderr)
sys.exit(1)
if macos == "true" and benchmark["result"] != "success":
print(
f"Activation benchmark was required but did not pass: {benchmark['result']}",
file=sys.stderr,
)
sys.exit(1)
if macos != "true" and benchmark["result"] not in {"success", "skipped"}:
print(
f"Activation benchmark had unexpected result for macos={macos}: {benchmark['result']}",
file=sys.stderr,
)
sys.exit(1)
print(f"changes.macos={macos}")
print(f"activation-session-benchmark={benchmark['result']}")
PY