-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
ci: onboard Blacksmith Testbox #10110
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
lawrencecchen
wants to merge
38
commits into
main
Choose a base branch
from
feat-blacksmith-testbox-onboarding
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 3 commits
Commits
Show all changes
38 commits
Select commit
Hold shift + click to select a range
0fc9b15
ci: onboard Blacksmith Testbox
lawrencecchen e407046
ci: provision cmux-tui Rust Testbox lane
lawrencecchen 67f398f
ci: serialize Testbox benchmark stages
lawrencecchen 5e31e66
ci: harden trusted Blacksmith Testbox lane
lawrencecchen 33b0dfe
docs: tighten Testbox source preflight
lawrencecchen 22800c1
ci: serialize and recover trusted Testbox runs
lawrencecchen 42ab3da
ci: bind Testbox cleanup to setup receipts
lawrencecchen 5735ee5
ci: pin Testbox hydration failure reporting
lawrencecchen bc7ff77
ci: bound and verify remote Testbox builds
lawrencecchen 5cdb5fc
ci: verify Testbox ready phone-home
lawrencecchen 94c6187
ci: fence setup markers and preserve evidence
lawrencecchen 5da1401
docs: state Testbox trust configuration limits
lawrencecchen bd89ec7
ci: preview owned Testbox cleanup
lawrencecchen c1999b8
ci: assert trusted runner identity
lawrencecchen ba2fd40
ci: finalize Testbox readiness and cleanup states
lawrencecchen dd3765c
ci: make Testbox readiness and cleanup explicit
lawrencecchen b0c5b80
ci: gate Testbox readiness and destructive cleanup
lawrencecchen 4a05ae6
ci: verify Testbox ownership before cleanup
lawrencecchen 1c95667
ci: restrict Testbox token setup to main
lawrencecchen 1dd0e2a
ci: validate Testbox inputs before cleanup
lawrencecchen 7e1e7cc
ci: align Testbox cleanup with CLI inventory
lawrencecchen 3c283ab
ci: make Testbox cleanup status-specific
lawrencecchen 4465525
ci: parse Testbox status formats safely
lawrencecchen 9fc1b55
ci: require a current Testbox cleanup preview
lawrencecchen 63d74f3
ci: close final Testbox trust gaps
lawrencecchen d0e7108
ci: bound Testbox control-plane operations
lawrencecchen 905939f
ci: use portable bounded Testbox commands
lawrencecchen ad1206b
ci: require preview-bound Testbox cleanup
lawrencecchen 53fbe79
docs: bound Testbox downloads and cleanup hashing
lawrencecchen d210746
ci: handle Testbox metadata and CLI schema drift
lawrencecchen 229119d
ci: tighten Testbox ownership parsing
lawrencecchen 07c1856
ci: enforce hydrated toolchain identity
lawrencecchen 2af052b
ci: bound warmup and preserve interrupted stages
lawrencecchen 89bd10d
ci: compare toolchain identity in cmux-tui
lawrencecchen 5c529ba
ci: own bounded Testbox keepalive
lawrencecchen 6042481
ci: fix keepalive SSH activity detection
lawrencecchen 00634a2
docs: require independently reviewed cleanup preview
lawrencecchen 1f21d21
ci: pin reviewed Testbox branch and SHA
lawrencecchen File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| name: cmux-tui Rust Testbox setup | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| inputs: | ||
| testbox_id: | ||
| description: "Testbox session ID supplied by blacksmith testbox warmup" | ||
| required: true | ||
| type: string | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| cmux-tui-rust: | ||
| name: cmux-tui Rust setup | ||
| runs-on: blacksmith-32vcpu-ubuntu-2404 | ||
| timeout-minutes: 45 | ||
| steps: | ||
| # begin-testbox must be the first step. It attaches the VM requested by | ||
| # `blacksmith testbox warmup` and leaves it alive after this setup job. | ||
| - name: Begin Testbox | ||
| uses: useblacksmith/begin-testbox@233448af4bfdc6fca509a7f0974411ac6d8a8043 # v2 | ||
| with: | ||
| testbox_id: ${{ inputs.testbox_id }} | ||
|
|
||
| - name: Checkout exact dispatch commit | ||
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | ||
| with: | ||
| fetch-depth: 0 | ||
| persist-credentials: false | ||
| ref: ${{ github.sha }} | ||
|
|
||
| - name: Require exact checkout | ||
| env: | ||
| EXPECTED_SHA: ${{ github.sha }} | ||
| shell: bash | ||
| run: | | ||
| actual_sha="$(git rev-parse HEAD)" | ||
| if [[ "$actual_sha" != "$EXPECTED_SHA" ]]; then | ||
| echo "::error::checked out $actual_sha, expected dispatch SHA $EXPECTED_SHA" >&2 | ||
| exit 1 | ||
| fi | ||
| printf 'testbox setup commit: %s\n' "$actual_sha" | ||
|
|
||
| - name: Initialize Ghostty source submodule | ||
| shell: bash | ||
| run: | | ||
| git submodule update --init --depth 1 ghostty | ||
| test -f ghostty/build.zig.zon | ||
|
|
||
| - name: Install Linux build dependencies | ||
| shell: bash | ||
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y clang libclang-dev pkg-config | ||
|
|
||
| - name: Cache Zig package downloads | ||
| uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | ||
| with: | ||
| path: ~/.cache/zig | ||
| key: cmux-tui-zig-${{ hashFiles('ghostty/build.zig.zon', 'ghostty/build.zig.zon.json') }} | ||
| restore-keys: | | ||
| cmux-tui-zig- | ||
|
|
||
| - name: Install repository-pinned Zig | ||
| shell: bash | ||
| run: ./scripts/install-zig-ci.sh | ||
|
|
||
| - name: Fetch Ghostty Zig dependencies without compiling | ||
| working-directory: ghostty | ||
| shell: bash | ||
| run: | | ||
| # `--fetch` hydrates the package cache and exits before a build. | ||
| "$CMUX_ZIG" build --fetch | ||
|
|
||
| - name: Cache Cargo registry and git dependencies | ||
| uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | ||
| with: | ||
| path: | | ||
| ~/.cargo/registry | ||
| ~/.cargo/git | ||
| key: cmux-tui-cargo-${{ runner.os }}-${{ hashFiles('cmux-tui/Cargo.lock', 'cmux-tui/rust-toolchain.toml') }} | ||
| restore-keys: | | ||
| cmux-tui-cargo-${{ runner.os }}- | ||
|
|
||
| - name: Set up repository-pinned cmux-tui Rust | ||
| uses: ./.github/actions/setup-cmux-tui-rust | ||
|
|
||
| - name: Fetch Cargo dependencies without compiling | ||
| working-directory: cmux-tui | ||
| shell: bash | ||
| run: cargo fetch --locked | ||
|
|
||
| - name: Record hydrated toolchain and workspace metadata | ||
| working-directory: cmux-tui | ||
| shell: bash | ||
| run: | | ||
| printf 'rust-toolchain: ' | ||
| rustup show active-toolchain | ||
| printf 'cargo: ' | ||
| cargo --version | ||
| printf 'rustc: ' | ||
| rustc --version | ||
| printf 'zig: ' | ||
| "$CMUX_ZIG" version | ||
| cargo metadata --locked --no-deps --format-version 1 > "$RUNNER_TEMP/cmux-tui-cargo-metadata.json" | ||
| test -s "$RUNNER_TEMP/cmux-tui-cargo-metadata.json" | ||
|
|
||
| # Always hand control back to Testbox. Warmup is setup-only: all actual | ||
| # Rust builds are issued later with `blacksmith testbox run`. | ||
| - name: Run Testbox | ||
| uses: useblacksmith/run-testbox@5ca05834db1d3813554d1dd109e5f2087a8d7cbc # v2 | ||
| if: always() | ||
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,129 @@ | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
|
|
||
| # This helper is intentionally remote-only. The local benchmark plan invokes it | ||
| # through `blacksmith testbox run`; the guard makes an accidental local launch a | ||
| # no-op instead of running a Rust build on the developer's Mac. | ||
| if [[ "${CMUX_TESTBOX_REMOTE:-}" != "1" ]]; then | ||
| echo "refusing to run outside a Blacksmith Testbox (set CMUX_TESTBOX_REMOTE=1 only in the remote command)" >&2 | ||
| exit 64 | ||
| fi | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| if [[ $# -ne 1 ]]; then | ||
| echo "usage: CMUX_TESTBOX_REMOTE=1 $0 {first-clean|incremental-noop|changed-file}" >&2 | ||
| exit 64 | ||
| fi | ||
|
|
||
| stage="$1" | ||
| case "$stage" in | ||
| first-clean|incremental-noop|changed-file) ;; | ||
| *) | ||
| echo "unsupported benchmark stage: $stage" >&2 | ||
| exit 64 | ||
| ;; | ||
| esac | ||
|
|
||
| repo_root="$(git rev-parse --show-toplevel)" | ||
| cd "$repo_root" | ||
| if [[ ! -f cmux-tui/Cargo.toml || ! -f ghostty/.git || ! -f ghostty/build.zig.zon ]]; then | ||
| echo "cmux-tui and its Ghostty source submodule must be initialized" >&2 | ||
| exit 65 | ||
| fi | ||
|
|
||
| benchmark_dir="$repo_root/testbox-benchmark" | ||
| mkdir -p "$benchmark_dir" | ||
| # Testbox can acknowledge a run while its remote shell is still flushing | ||
| # output. Serialize stages and hold the lock through artifact writes so a | ||
| # subsequent run cannot overwrite a prior stage's timing file. | ||
| exec 9>"$benchmark_dir/.stage.lock" | ||
| flock -x 9 | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| log_path="$benchmark_dir/$stage.log" | ||
| time_path="$benchmark_dir/$stage.time" | ||
| json_path="$benchmark_dir/$stage.json" | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| changed_file="cmux-tui/crates/cmux-tui/src/main.rs" | ||
| changed_backup="" | ||
|
|
||
| # shellcheck disable=SC2329 # invoked indirectly by the EXIT trap | ||
| restore_changed_file() { | ||
| if [[ -n "$changed_backup" && -f "$changed_backup" ]]; then | ||
| cp "$changed_backup" "$repo_root/$changed_file" | ||
| rm -f "$changed_backup" | ||
| fi | ||
| } | ||
| trap restore_changed_file EXIT | ||
|
|
||
| case "$stage" in | ||
| first-clean) | ||
| rm -rf "$repo_root/cmux-tui/target" | ||
| ;; | ||
| changed-file) | ||
| changed_backup="$(mktemp "${TMPDIR:-/tmp}/cmux-tui-testbox-source.XXXXXX")" | ||
| cp "$repo_root/$changed_file" "$changed_backup" | ||
| printf '\n// Blacksmith Testbox changed-file timing marker.\n' >> "$repo_root/$changed_file" | ||
| ;; | ||
| esac | ||
|
|
||
| start_epoch="$(python3 -c 'import time; print(time.time())')" | ||
| set +e | ||
| ( | ||
| cd "$repo_root/cmux-tui" | ||
| /usr/bin/time -p -o "$time_path" cargo build -p cmux-tui --locked | ||
| ) >"$log_path" 2>&1 | ||
| status=$? | ||
| set -e | ||
| end_epoch="$(python3 -c 'import time; print(time.time())')" | ||
|
|
||
| python3 - "$stage" "$start_epoch" "$end_epoch" "$status" "$time_path" "$changed_file" >"$json_path" <<'PY' | ||
| import datetime as dt | ||
| import json | ||
| import os | ||
| import platform | ||
| import subprocess | ||
| import sys | ||
|
|
||
| stage, start, end, status, time_path, changed_file = sys.argv[1:] | ||
| start = float(start) | ||
| end = float(end) | ||
| status = int(status) | ||
| remote_time = {} | ||
| with open(time_path, encoding="utf-8") as handle: | ||
| for line in handle: | ||
| key, _, value = line.strip().partition(" ") | ||
| if key in {"real", "user", "sys"}: | ||
| remote_time[f"time_{key}_seconds"] = float(value) | ||
|
|
||
| try: | ||
| git_sha = subprocess.check_output( | ||
| ["git", "rev-parse", "HEAD"], text=True, stderr=subprocess.DEVNULL | ||
| ).strip() | ||
| except subprocess.CalledProcessError: | ||
| git_sha = "unknown" | ||
|
|
||
| record = { | ||
| "schema": 1, | ||
| "stage": stage, | ||
| "command": "cargo build -p cmux-tui --locked", | ||
| "exit_code": status, | ||
| "ok": status == 0, | ||
| "started_at": dt.datetime.fromtimestamp(start, dt.timezone.utc).isoformat(), | ||
| "finished_at": dt.datetime.fromtimestamp(end, dt.timezone.utc).isoformat(), | ||
| "wall_seconds": round(end - start, 3), | ||
| "git_sha": git_sha, | ||
| "runner": { | ||
| "hostname": platform.node(), | ||
| "arch": platform.machine(), | ||
| "cpu_count": os.cpu_count(), | ||
| "uname": " ".join(platform.uname()), | ||
| }, | ||
| "changed_file": changed_file if stage == "changed-file" else None, | ||
| **remote_time, | ||
| } | ||
| print(json.dumps(record, sort_keys=True)) | ||
| PY | ||
|
|
||
| cat "$log_path" | ||
| printf '\n--- /usr/bin/time -p (%s) ---\n' "$stage" | ||
| cat "$time_path" | ||
| printf '\n--- structured timing (%s) ---\n' "$stage" | ||
| cat "$json_path" | ||
| exit "$status" | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When this workflow is dispatched from another repository on its
mainbranch, the ref guard passes andBegin Testboxruns beforeREPOSITORYis checked at lines 69–72. Because the begin action installs the Testbox authentication token, the declaredmanaflow-ai/cmuxrestriction is enforced too late for the token-bearing step; include the repository predicate in the pre-begin guard.Useful? React with 👍 / 👎.