Repository navigation
ci: run Rust builds and tests on Blacksmith testboxes #36
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
Merged
+162
−0
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
6f9ddbd
ci: run Rust builds and tests on Blacksmith testboxes
t3dotgg 1b311ea
ci(testbox): stop an idle testbox after 15 minutes
t3dotgg ac9bc27
fix(testbox): keep argument boundaries in run, keep the saved ID on a…
t3dotgg 7564655
fix(testbox): print warmup output when warmup fails
t3dotgg 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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| # A Blacksmith testbox: a warm Linux x64 runner that runs builds and tests against the local tree | ||
| # (scripts/goport/testbox.sh). `blacksmith testbox warmup` dispatches this workflow, `testbox run` syncs | ||
| # the working tree to it and runs one command. The setup matches the Linux test job of ci.yml, with | ||
| # zbook's toolchains. Sticky disks keep target/ and the cargo registry warm between testboxes. | ||
| # A pull request that changes this file runs it in validation mode (no testbox_id). | ||
| name: Blacksmith Testbox | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| inputs: | ||
| testbox_id: | ||
| type: string | ||
| description: "Testbox session ID" | ||
| required: true | ||
| pull_request: | ||
| paths: | ||
| - ".github/workflows/testbox.yml" | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: | ||
| group: testbox-${{ inputs.testbox_id || github.ref }} | ||
| cancel-in-progress: false | ||
|
|
||
| env: | ||
| CARGO_TERM_COLOR: always | ||
| # The toolchain of shipped bins and --profile goport. Edit-loop builds use the nightly of | ||
| # scripts/run-cargo-capped.sh. | ||
| RUSTUP_TOOLCHAIN: 1.93.0 | ||
| NIGHTLY_TOOLCHAIN: nightly-2026-06-17 | ||
|
|
||
| jobs: | ||
| testbox: | ||
| runs-on: blacksmith-32vcpu-ubuntu-2404 | ||
| timeout-minutes: 360 | ||
| steps: | ||
| - name: Begin Testbox | ||
| uses: useblacksmith/begin-testbox@v2 | ||
| with: | ||
| testbox_id: ${{ inputs.testbox_id }} | ||
| - uses: actions/checkout@v5 | ||
| with: | ||
| persist-credentials: false | ||
| # After checkout: its clean step would empty a disk mounted in the workspace. | ||
| - uses: useblacksmith/stickydisk@v1 | ||
| with: | ||
| key: ts-rust-testbox-target | ||
| path: ${{ github.workspace }}/target | ||
| - uses: useblacksmith/stickydisk@v1 | ||
| with: | ||
| key: ts-rust-testbox-cargo | ||
| path: ~/.cargo/registry | ||
| # main's Go pin is the saved state's batch.upstreamPin.to (AGENTS.md, "Pin"). The Go checkout sits | ||
| # outside the workspace, so a sync of the local tree does not touch it. | ||
| - name: Resolve the Go pin | ||
| id: pin | ||
| run: | | ||
| key=$(jq -r '.batch.upstreamPin.to // empty' docs/typechecker-state/current.json) | ||
| python3 scripts/upstream/pin.py show ${key:+"$key"} > "$RUNNER_TEMP/pin.json" | ||
| jq -r '"repo=\(.repo)", "commit=\(.commit)", "subdir=\(.subdir // "")", "go=\(.oracle.go | ltrimstr("go"))"' "$RUNNER_TEMP/pin.json" >> "$GITHUB_OUTPUT" | ||
| - name: Check out the pinned Go source | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| repository: ${{ steps.pin.outputs.repo }} | ||
| ref: ${{ steps.pin.outputs.commit }} | ||
| path: go-pin | ||
| sparse-checkout: ${{ steps.pin.outputs.subdir }} | ||
| persist-credentials: false | ||
| - name: Install the Go repo's typescript package | ||
| run: | | ||
| url=$(jq -r '.packages["node_modules/typescript"].resolved' go-pin/package-lock.json) | ||
| mkdir -p go-pin/node_modules/typescript | ||
| curl -sSfL "$url" | tar xz -C go-pin/node_modules/typescript --strip-components=1 | ||
| mv go-pin "$HOME/go-pin" | ||
| - uses: actions/setup-go@v6 | ||
| with: | ||
| go-version: ${{ steps.pin.outputs.go }} | ||
| cache: false | ||
| - run: | | ||
| rustup toolchain install "$RUSTUP_TOOLCHAIN" --profile minimal -c rustfmt,clippy | ||
| rustup toolchain install "$NIGHTLY_TOOLCHAIN" --profile minimal | ||
| # Remote commands run without this job's RUSTUP_TOOLCHAIN. 1.93.0 is the default, as on zbook; | ||
| # run-cargo-capped.sh picks the nightly for edit-loop builds. | ||
| rustup default "$RUSTUP_TOOLCHAIN" | ||
| # testbox.sh sources this file before each command: commands run over SSH, without this job's env. | ||
| # TS_CARGO_CGROUP_ACTIVE=1 skips the systemd user scope of run-cargo-capped.sh (no user session here). | ||
| - name: Write the testbox env | ||
| env: | ||
| SUBDIR: ${{ steps.pin.outputs.subdir }} | ||
| run: | | ||
| cat > "$HOME/testbox.env" <<EOF | ||
| export PATH="$(dirname "$(command -v go)"):$HOME/.cargo/bin:\$PATH" | ||
| export CARGO_TERM_COLOR=always | ||
| export TS_GO_REPO="$HOME/go-pin${SUBDIR:+/$SUBDIR}" | ||
| export TSCTEST_TMP="$RUNNER_TEMP/tsctest" | ||
| export COMPILER_RUNNER_TMP="$RUNNER_TEMP/compiler-runner" | ||
| export TS_CARGO_CGROUP_ACTIVE=1 | ||
| export TS_CARGO_JOBS=32 | ||
| export TS_CARGO_SLOTS=1 | ||
| EOF | ||
| cat "$HOME/testbox.env" | ||
| - name: Run Testbox | ||
| uses: useblacksmith/run-testbox@v2 | ||
| if: always() | ||
|
t3dotgg marked this conversation as resolved.
t3dotgg marked this conversation as resolved.
|
||
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,57 @@ | ||
| #!/usr/bin/env bash | ||
| # Blacksmith testboxes: a warm 32 vCPU Linux x64 runner (.github/workflows/testbox.yml) that runs a command | ||
| # against this worktree's files. `run` syncs this worktree to the testbox (the CLI's rsync) and runs the | ||
| # command in the synced repo root. target/ and the cargo registry sit on sticky disks. | ||
| # usage: testbox.sh help this text | ||
| # testbox.sh warmup start a testbox; saves its ID to target/testbox-id | ||
| # testbox.sh run <command...> sync this worktree, then run the command with the testbox env | ||
| # (e.g. run scripts/run-cargo-capped.sh build --release -p ts_goport --bins). | ||
| # Arguments keep their boundaries; use run bash -c '...' for pipes and && | ||
| # testbox.sh get <remote> [local] copy a file or dir back (remote path relative to the repo root) | ||
| # testbox.sh status | stop | list the saved testbox's status, stop it, list active testboxes | ||
| # TESTBOX_ID overrides the saved ID. TESTBOX_IDLE: idle minutes before the testbox stops (default 15). | ||
| # TESTBOX_REF: the ref the workflow runs from (default main: the workflow must be on the default branch). | ||
| # Auth: `blacksmith auth login` once per host (`blacksmith auth status` shows it). | ||
| set -euo pipefail | ||
| case "${1:-help}" in help | -h | --help) sed -n '2,/^set -euo/p' "$0" | sed '$d'; exit 0 ;; esac | ||
|
|
||
| repo_root="$(git -C "$(dirname -- "${BASH_SOURCE[0]}")" rev-parse --show-toplevel)" | ||
| id_file="$repo_root/target/testbox-id" | ||
| cd "$repo_root" | ||
|
|
||
| saved_id() { | ||
| local id="${TESTBOX_ID:-$(cat "$id_file" 2>/dev/null || true)}" | ||
| [[ -n "$id" ]] || { echo "no testbox: run 'testbox.sh warmup' or set TESTBOX_ID" >&2; exit 2; } | ||
| echo "$id" | ||
| } | ||
|
|
||
| cmd="$1" | ||
| shift | ||
| case "$cmd" in | ||
| warmup) | ||
|
macroscopeapp[bot] marked this conversation as resolved.
|
||
| rc=0 | ||
| out="$(blacksmith testbox warmup testbox.yml --ref "${TESTBOX_REF:-main}" --idle-timeout "${TESTBOX_IDLE:-15}" 2>&1)" || rc=$? | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| echo "$out" | ||
| ((rc == 0)) || exit "$rc" | ||
| id="$(grep -oE 'tbx_[A-Za-z0-9_-]+' <<<"$out" | head -1)" | ||
| [[ -n "$id" ]] || { echo "warmup printed no testbox ID" >&2; exit 1; } | ||
| mkdir -p "$(dirname "$id_file")" | ||
| echo "$id" >"$id_file" | ||
| echo "testbox $id (saved to target/testbox-id)" | ||
| ;; | ||
| run) | ||
| (($#)) || { echo "usage: testbox.sh run <command...>" >&2; exit 2; } | ||
| printf -v remote_cmd '%q ' "$@" | ||
| blacksmith testbox run --id "$(saved_id)" ". ~/testbox.env && $remote_cmd" | ||
| ;; | ||
| get) blacksmith testbox download --id "$(saved_id)" "$@" ;; | ||
| status) blacksmith testbox status --id "$(saved_id)" "$@" ;; | ||
| stop) | ||
| id="$(saved_id)" | ||
| blacksmith testbox stop --id "$id" | ||
| # Keep the saved ID when TESTBOX_ID stopped another testbox. | ||
| [[ "$(cat "$id_file" 2>/dev/null || true)" != "$id" ]] || rm -f "$id_file" | ||
| ;; | ||
| list) blacksmith testbox list "$@" ;; | ||
| *) echo "unknown command: $cmd (testbox.sh help)" >&2; exit 2 ;; | ||
| esac | ||
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.
Uh oh!
There was an error while loading. Please reload this page.