Repository navigation
ci: build and test on a self-hosted macOS runner - #2
Merged
Merged
Conversation
No CI existed. GitHub bills macOS runners at a 10x minute multiplier on private repos, so one 5-8 minute build+test burns 50-80 billed minutes — the free allowance (2,000 min/month = 200 macOS minutes) covers roughly three runs a month. Untenable for a repo under active development. Self-hosted is safe HERE because this repo is private. Do not copy this workflow to a public repo: a fork's pull_request can execute arbitrary code on the runner. That caveat applies to link-devices. The suite itself takes 0.7 seconds; all the cost is compiling and booting a simulator, both of which a warm persistent machine keeps around. Notes: the runner service does not inherit a login shell's PATH, so /opt/homebrew/bin is added explicitly or xcodegen is not found. The .xcodeproj is gitignored and regenerated from project.yml on every run.
…om the code gstack: /browse for all web browsing, never mcp__claude-in-chrome__* directly. The KitchenSync rules worth encoding are the ones a new agent (or human) will get WRONG by reading the code alone: - Live vs reboot IS the KsLiveEdit case list, and it is not guessable from field names: metro_accent is live, metronome ENABLE is not; led enable IS live, follow_beat is not. Names the three structural defenses and says not to weaken them. - Transport is quantized. Never predict armed->running client-side. - XcodeGen REGENERATES Info.plist from project.yml, so hand-edits to it vanish. And NSLocalNetworkUsageDescription / NSBonjourServices are load-bearing: without them iOS silently kills Bonjour and .local resolution with no useful error. - TDD is the rule; network tests run the real client against a stubbed wire. - The known gap: nothing has ever spoken to real hardware.
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.
There was no CI at all — zero workflows, zero runners.
Why self-hosted rather than GitHub-hosted
GitHub bills macOS runners at a 10× minute multiplier on private repos (Linux 1×, Windows 2×). Our pipeline is
xcodegen+xcodebuild+ boot a simulator, roughly 5–8 minutes wall clock — so 50–80 billed minutes per run. The free allowance (2,000 min/month → 200 macOS minutes) covers about three runs a month. Untenable for a repo under active development.Worth knowing where the cost actually sits: the 86 tests run in 0.7 seconds. Everything else is compiling and booting a simulator — both of which a warm, persistent machine keeps around. Incremental runs on the self-hosted box should land well under a minute, versus 5–8 cold.
Safety
Self-hosted is safe here specifically because this repo is private. Do NOT copy this workflow to a public repo — a fork's
pull_requestcan execute arbitrary code on the runner. That caveat applies tolink-devices, which is public.Two things that would otherwise bite
/opt/homebrew/binis added explicitly via$GITHUB_PATH. Without it,xcodegenisn't found..xcodeprojis gitignored, so it's regenerated fromproject.ymlon every run — which also regeneratesInfo.plist.Gated on
Sources/**,Tests/**,project.yml, and the workflow itself, withcancel-in-progressso two quick pushes don't queue two builds on one machine. Failed runs upload the.xcresultbundle.Runner registered and online as
LIB-2833(self-hosted,macOS,ARM64), installed as a launchd service so it survives reboots.https://claude.ai/code/session_01F7YsQgso3KNpeXbP5vNVj6