Register your runner in 10 minutes.
Your MacRun box is a standard self-hosted GitHub Actions runner. Keep your pipeline; change two lines of YAML.
Get a registration token from GitHub
In your repo (or org) go to Settings → Actions → Runners → New runner. GitHub shows a one-time token. You'll paste it into the command below. Org-level runners are shared across all repos in the org.
Register the runner on your box
SSH in with the Tailscale invite from your credentials email, then run the configure command from your portal (it pre-fills your unit's label):
cd ~/actions-runner ./config.sh --url https://github.com/YOUR-ORG/YOUR-REPO \ --token <RUNNER_TOKEN> \ --labels self-hosted,macOS,macrun-unit-01 \ --unattended # start it as a service (survives reboots) ./svc.sh install && ./svc.sh start
The runner-agent daemon keeps this service alive automatically — if it crashes, it's restarted within 30 seconds.
Change two lines of YAML
Point your workflow at the runner. That's the whole diff:
jobs: build: - runs-on: macos-14 + runs-on: [self-hosted, macOS, macrun-unit-01]
Everything else in your pipeline stays exactly the same.
Xcode versions
Recent Xcode releases are preinstalled and pinned via xcodes. Select one in your job, or request a new version from your portal (usually same-day):
- run: sudo xcodes select 16.2 - run: xcodebuild -version
Caches are already warm
Because the machine is yours, caches persist between runs on local disk — no re-download tax. Common paths:
~/Library/Developer/Xcode/DerivedData # build cache ~/Library/Caches/CocoaPods # pods ~/.gradle ~/.npm ~/.gem # toolchain caches ~/Library/Caches/org.swift.swiftpm # SwiftPM
You can still use actions/cache if you want deterministic restore keys, but for most iOS builds the warm local disk is the win.
Manage your machine
Reboot, request Xcode versions, and manage billing from your portal. Need something else? Reply to any MacRun email — a human answers.