Repository navigation
ci: add reload-build workflow for cloud reload Blacksmith builder - #6354
Conversation
…ilder [skip ci] reload-cloud.sh / reload-cloud-ios.sh --builder blacksmith dispatch this to build a tagged dev macOS app or unsigned iOS archive on a Blacksmith macOS runner and upload it for local download. workflow_dispatch only, so it never joins the push/PR CI fan-out. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughA new manually triggered GitHub Actions workflow Changesreload-build Workflow
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 4b9de05. Configure here.
| if ! ios_ready; then | ||
| echo "iOS platform not registered; installing via downloadPlatform iOS" | ||
| xcodebuild -downloadPlatform iOS 2>&1 | tr '\r' '\n' | grep -ivE 'Preparing to download|registering download' | tail -8 || true | ||
| ios_ready || { echo "iOS platform still not registered; archive would fail" >&2; exit 1; } |
There was a problem hiding this comment.
ios_ready grep never matches
High Severity
The ios_ready helper looks for iOS … (Ready) in xcrun simctl runtime list, but typical output lists runtimes like iOS 18.0 (22A3351) with a build number in parentheses, not (Ready). After xcodebuild -downloadPlatform iOS, the same check still fails and the step exits before archiving.
Reviewed by Cursor Bugbot for commit 4b9de05. Configure here.
| run: | | ||
| set -euo pipefail | ||
| slug="$(printf '%s' "$BUILD_TAG" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9-' '-' | sed 's/-\{2,\}/-/g; s/^-//; s/-$//')" | ||
| bundle_id="dev.cmux.ios.$slug" |
There was a problem hiding this comment.
Empty iOS slug breaks bundle
Medium Severity
The iOS slug sanitizer can produce an empty string when the dev tag has no alphanumeric characters, yielding bundle id dev.cmux.ios. with no suffix. ios/scripts/reload.sh’s sanitize_tag falls back to dev and rejects unusable tags; this workflow does neither before xcodebuild archive.
Reviewed by Cursor Bugbot for commit 4b9de05. Configure here.
| - name: Build tagged macOS app | ||
| if: ${{ inputs.platform == 'macos' }} | ||
| id: build_macos | ||
| run: | | ||
| set -euo pipefail | ||
| ./scripts/reload.sh --tag "${{ inputs.tag }}" --swift-frontend-workaround 2>&1 | tee /tmp/reload.log |
There was a problem hiding this comment.
The macOS build step inlines
${{ inputs.tag }} directly into the shell command. GitHub Actions evaluates ${{ }} expressions before passing the string to the shell, so a tag like foo" --extra-flag or $(evil) is injected verbatim, turning the reload.sh invocation into arbitrary shell execution. The iOS step already does this correctly by binding the value to BUILD_TAG via env: and referencing $BUILD_TAG in the script — apply the same pattern here.
| - name: Build tagged macOS app | |
| if: ${{ inputs.platform == 'macos' }} | |
| id: build_macos | |
| run: | | |
| set -euo pipefail | |
| ./scripts/reload.sh --tag "${{ inputs.tag }}" --swift-frontend-workaround 2>&1 | tee /tmp/reload.log | |
| - name: Build tagged macOS app | |
| if: ${{ inputs.platform == 'macos' }} | |
| id: build_macos | |
| env: | |
| BUILD_TAG: ${{ inputs.tag }} | |
| run: | | |
| set -euo pipefail | |
| ./scripts/reload.sh --tag "$BUILD_TAG" --swift-frontend-workaround 2>&1 | tee /tmp/reload.log |
| cat > artifact/timings.json <<JSON | ||
| { | ||
| "tag": "${{ inputs.tag }}", | ||
| "platform": "${{ inputs.platform }}", | ||
| "runner": "${{ inputs.runner }}", | ||
| "ref": "${{ inputs.ref }}", |
There was a problem hiding this comment.
The
tag and ref inputs are expanded by the GitHub Actions template engine directly inside the heredoc body, before the shell runs. A tag containing a " character (e.g. v1.0"injected) will produce syntactically invalid JSON in timings.json. Since t0 has no || 0 fallback (unlike t1), an empty steps.t0.outputs.epoch — which can happen if the timer step was skipped on a cancellation path — would also cause an arithmetic error in the $(( now - t0 )) expressions.
| cat > artifact/timings.json <<JSON | |
| { | |
| "tag": "${{ inputs.tag }}", | |
| "platform": "${{ inputs.platform }}", | |
| "runner": "${{ inputs.runner }}", | |
| "ref": "${{ inputs.ref }}", | |
| cat > artifact/timings.json <<JSON | |
| { | |
| "tag": "$TAG", | |
| "platform": "${{ inputs.platform }}", | |
| "runner": "${{ inputs.runner }}", | |
| "ref": "$REF", |
| set -euo pipefail | ||
| mkdir -p artifact | ||
| now=$(date +%s) | ||
| t0=${{ steps.t0.outputs.epoch }} |
There was a problem hiding this comment.
t0 missing fallback — if the "Start timer" step is skipped (e.g. on a mid-run cancellation that still lets always() steps execute), steps.t0.outputs.epoch is empty and t0=${{ steps.t0.outputs.epoch }} expands to t0=, making every $(( … - t0 )) arithmetic expression fail. t1 already has || 0 for exactly this reason; t0 should too.


Adds
.github/workflows/reload-build.yml, aworkflow_dispatch-only build that the cmuxterm-hq cloud reload scripts use as their Blacksmith builder alternative to SSH-leasing a fleet Mac.scripts/reload-cloud.sh --builder blacksmithandscripts/reload-cloud-ios.sh --builder blacksmithdispatch this workflow against an ephemeral branch holding the caller's working tree, thengh run downloadthe artifact and install it locally (macOS: ad-hoc patch + install; iOS: local sign + devicectl install).cmux DEV <tag>.appvia the samescripts/reload.shthe fleet uses, zips it..xcarchivefordev.cmux.ios.<slug>(signed locally by the caller).runs-on: ${{ inputs.runner }}, defaultblacksmith-6vcpu-macos-26(all options are existing actionlint labels).timings.json+ step summary) for the Blacksmith-vs-fleet comparison.workflow_dispatchonly: nopush/pull_requesttriggers, so it never adds to the heavy CI fan-out. Committed with[skip ci]to keep this PR off the paid runners.Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.Note
Low Risk
CI-only addition with read-only repo permissions and no push/PR triggers; reuses existing build scripts without changing app runtime code.
Overview
Adds a
workflow_dispatch-only GitHub Actions workflow so cloud reload scripts can build tagged dev artifacts on Blacksmith (or other macOS runners) instead of leasing a fleet Mac.Callers pass tag, optional ref, platform (
macos|ios), runner, and a nonce echoed inrun-nameso the dispatcher can find the run. Concurrency cancels in-flight builds for the same tag+platform.macOS runs
scripts/reload.shwith the tag, zips the built app. iOS produces an unsigned Debug.xcarchivewithdev.cmux.ios.<slug>(signing stays local). Shared setup: checkout, Xcode selection, zig install, GhosttyKit provisioning,CMUX_SKIP_ZIG_BUILD=1. Outputstimings.jsonand a step summary, then uploads a 3-day artifact.No
push/pull_requesttriggers—manual dispatch only, so it does not expand the main CI fan-out.Reviewed by Cursor Bugbot for commit 4b9de05. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by cubic
Adds a
reload-buildGitHub Actions workflow to build a tagged dev macOS app or an unsigned iOS archive onBlacksmithmacOS runners for cloud reload, replacing fleet Mac SSH leases. It’s manual-only (workflow_dispatch) and uploads a ready-to-install artifact.New Features
.github/workflows/reload-build.ymlwith inputs:tag,ref,platform(macos|ios),runner,nonce.scripts/reload.shand zips it asapp.zip..xcarchivefordev.cmux.ios.<slug>asarchive.zip.reload-<tag>-<platform>withtimings.json; retention 3 days. Concurrency is per tag+platform; run name includes tag/platform/nonce.blacksmith-6vcpu-macos-26(other labels supported).Migration
scripts/reload-cloud.sh --builder blacksmithorscripts/reload-cloud-ios.sh --builder blacksmith.gh run downloadto fetch and install locally.Written for commit 4b9de05. Summary will update on new commits.
Summary by CodeRabbit