ci: add macOS arm64 runners to the wavekat-ci pool - #158
Merged
Conversation
`runs-on: [self-hosted, wavekat-ci]` is a label pool, not a machine, so adding the Mac mini is a registration problem rather than a workflow one. Add the macOS twin of the Linux setup/uninstall scripts, registering with the same `wavekat-ci` label so jobs land on whichever host is idle. macOS forces three differences from the Linux script: the osx-arm64 runner package, a launchd LaunchAgent instead of a systemd unit (so runners live under $HOME and need no sudo), and a per-runner `.path` file, since launchd does not source the shell profile and Homebrew would otherwise be invisible. A mixed pool also means any job can land on BSD userland, so `preview.yml` loses its `grep -oP` — BSD grep has no PCRE, and that step would have failed every time the deploy job landed on the Mac. `docs/06` records the rest of the portability traps and the headless-Mac requirements (auto-login, no sleep) that keep the agents online across reboots. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TxidDNZBX6a7YqiPdmjf6C
Contributor
Switches the macOS runners from a native launchd install to Docker Desktop containers, reusing the existing scripts/docker image. Reading the other repos on this label is what settles it: wavekat-voice's ci.yml runs `sudo apt-get install` three times, so every wavekat-ci job in that repo would have failed the moment it landed on a native macOS runner. macOS cannot run macOS containers, so Docker Desktop means the Mac contributes Linux/arm64 capacity — which is the goal, since nothing in the pool's workload needs macOS and a uniform Ubuntu userland removes the BSD-vs-GNU failure mode entirely. The image already resolved its arch via dpkg, so it builds natively on Apple Silicon unchanged. Supervision is Docker's own --restart unless-stopped rather than launchd; the reboot story is Docker Desktop's start-at-login plus auto-login. docs/06 now also records who else rides on this label — seven repos, with wavekat-voice and wavekat-asr building sherpa-onnx native code and so arch-sensitive. No shipped artifact is built on wavekat-ci (installers use GitHub-hosted runners), so a bad host means red CI, not a bad release. Recommends registering the Mac under wavekat-ci-arm64 first and opting repos in, rather than widening the label blind. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TxidDNZBX6a7YqiPdmjf6C
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Adds macOS (Apple Silicon) support to the self-hosted GitHub Actions runner pool, allowing CI jobs to run on either the existing Linux x86-64 workstation or a new Mac mini, both carrying the
wavekat-cilabel.Changes
scripts/setup-gha-runners-macos.sh: New script to install and register N launchd-based GitHub Actions runners on macOS. Mirrors the Linux setup script but usesactions-runner-osx-arm64, launchd LaunchAgents instead of systemd, and writes a.pathfile so Homebrew binaries are visible to the runner (launchd does not source shell profiles). Includes headless-Mac guidance (automatic login + sleep prevention).scripts/uninstall-gha-runners-macos.sh: Companion teardown script that stops launchd agents, de-registers runners from the org, and cleans up.docs/06-self-hosted-runners.md: Comprehensive guide covering:.pathfile, quarantine clearing)RUNNER_KEEP_AWAKE=1)run:block must be portable across BSD and GNU userland — documents the traps (nogrep -P,sed -isyntax,readlink -f,date -d,sha256sum,xargs -r, bash 3.2 limits) with POSIX-safe alternatives_workdirectory).github/workflows/preview.yml: Fixed the Cloudflare deployment alias extraction to use POSIXsedinstead ofgrep -oP, with an inline comment explaining the portability requirement. This was the only workflow change needed — the job now works on both Linux and macOS runners.CLAUDE.md: Added a section documenting the mixed-pool constraint and pointing to the full guide.Implementation notes
The macOS script handles several platform-specific details:
com.apple.quarantineattribute from curl-fetched tarballs (no-op in normal path, but prevents Gatekeeper from killing binaries)/opt/homebrewfor Apple Silicon,/usr/localfor Intel) and writes it into the runner's.pathso launchd-spawned processes can find itThe portability fix in
preview.ymlusessed -nE(extended regex, POSIX) with a character class[[:space:]]instead of\S, and pipes throughtail -n 1to handle multi-line output safely.https://claude.ai/code/session_01TxidDNZBX6a7YqiPdmjf6C