多くのプラットフォームチームが macOS ビルドに GitHub Actions、GitLab Runner、Jenkins のいずれかを運用していますが、キューの統合、複数リポジトリでのコスト可視化、VPS のように SSH 前提で扱える専用機 の運用には依然としてギャップがあります。本稿は iOS/macOS の実行を 専用リモート Mac に移すチーム向けに、Buildkite の導入を阻む 7 つの隠れた前提、Elastic CI 判断のための四者比較表、インストール・トークン・タグ・Hook・ヘルス・並列度を含む 六段の引き渡し Runbook、および GitHub Actions のセルフホスト Runner、GitLab Runner、Jenkins SSH Agent の関連記事へのリンクをまとめます。
Buildkite のコントロールプレーンはキューと権限の可視化に優れる一方で、macOS は相変わらず Xcode + Keychain + ディスク書き増幅率 の問題セットです。次の七点で「エージェントを付ける」という約束を、署名済みの運用契約に変換し、再現ビルド および SwiftPM/Pods と DerivedData のディスク運用 に接続してください。
Elastic CI と無限並列を混同しない: 弾力性は「ホストが仕事を受け取れるか」を示しますが、「単一ホストが複数の xcodebuild RAM 尖値や NVMe 競争を許容できるか」ではありません。並列キャップはハード値で決めること。
キュー/タグの意味を読み落とさない: Buildkite はタグでジャッジを振り分けます。すべての iOS ジョブが同じタグに刺されば重いセットアップと軽いスモークテストが衝突します。Runner ガイド のプロファイル方針を踏襲します。
Hook を雑シェル扱いにしない: 環境注入・シークレットマスク・クリーンアップはエージェントユーザー側の明示的フック経路へ置くべきで、ログイン環境への依存には逃げられません。
同一ユーザーに複数 buildkite-agent を無制限には載せない: 標準 DerivedData を共有すると Flaky が増えるのでユーザーを分割するか BUILDKITE_BUILD_PATH でバケットしてください。
「git clone だけ成功」を合格にしない: 署名・notary を通さない検収はリリースウィーク地雷になります。無人環境での公証 チェックリストと束ねます。
プロバイダ SSH メモをチャットに散らさない: ポート・踏み台・許可先・メンテ窓などはすべて一体の社内 Runbook にまとめます。
「ディスクの水位低下でスケジューラ停止」規程が無い: キューを詰めるほど Xcode/git の残骸が増えば待機より高くつくのは同様です。Enterprise 級ビルドプール と同様の論理になります。
共通の元凶は、「リモート Mac」を Xcode のフィンガープリントと Keychain を持つ実行ノードではなく単なるコンピュートと見なしている点です。Buildkite はワーク割当や失敗の筋道が見えますが、ディスク SLA・並列の天井線・クリーニング SLO はプラットフォーム側が担います。Jenkins と比べれば Groovy 肥大は収まっても実行面はそのままで、VPS 思考の組織ほど許容できるトレードオフになります。
並行運用している GitLab では GitLab Runner 記事 の resource_group 発想と同種のミューテックスを、Buildkite のキュー/クラスタに写し替えると整理しやすくなります。物理上限は結局この Mac が同時に何本の xcodebuild を背負えるかになります。
別の CI を足すべき論争に入る前に、まず三つの SLA(キュー P95 と 説明できる失敗 と 鍵輪転の実験結果)を書きください。イベントは GitHub/GitLab に張りついているのに横断キューとコスト可視性が無いとき、Buildkite は単なる別ラッパーではなくホンモノのボトルネックに刺さります。
万能の答えはなく、パイプライン定義の所在、キューと権限のオーナー、macOS ワーカーを長期専業に保てるかのいずれもトレードになります。レビュー議論をこの表に張り付け、ロゴ論争に時間を浪費しないでください。
| 観点 | Buildkite + Agent | GitHub Actions(セルフホスト) | GitLab Runner(shell) | Jenkins SSH agent |
|---|---|---|---|---|
| コントロールプレーン | Buildkite UI/API とリポジトリ内 pipeline.yml が段階を宣言 | ワークフロ YAML が PR と強く結合 | GitLab プロジェクト/MR と .gitlab-ci.yml | コントローラープラグインと Job DSL——柔軟だが構成ドリフトに弱い |
| 弾性 | Elastic agents/キューラウティング/タグ重視 | Runner 登録+自己管理並列 | Runner 並列+ resource_group 由来のミューテックス | ラベル+絞込みプラグイン——成熟度は高く冗長 |
| 機密・監査 | Buildkite secrets と Hook、輪転は自前 Runbook | GitHub Secrets + OIDC パターン | マスク/保護フラグ付き CI/CD 変数 | 資格情報ドメインがコントローラの爆風へ同期 |
| 得意領域 | 複数 Repo のキューをまたぎ SSH 優先の専門 Mac と噛む | GitHub に寄せた PR の配信モデル | GitLab に寄せた MR のパイプライン | オンプレ成果物/承認/混在 Git での統括 |
Buildkite の語彙では「Mac を VPS 感覚で借りる」とはルーティング可能なエージェント・プロファイルを購入することです。SSH を固定すること、SSD レイヤーを計画すること、タグへ Xcode を焼けること。
プルリクエストのワークフローが GitHub 中心である一方、少数台の macOS を部門またぎで回すときはチェックだけ Actions に残し、重いアーカイブ処理・公証・長時間の統合は Buildkite キューが同じリモート Mac を指すという折衷がよく使われます。いずれにせよ両スタック間でディスクの根/秘密情報ドメイン は分離し、混線させないようにします。
Apple 管理ぶんとの比較は Xcode Cloud 対リモート専用 Mac で整理すると役立ちます。本稿では macOS 実行面自体を自分で請け負う前提です。
長期租用のノードへ踏み込むならすべてを単発 Shell に押し込まず、キュー見える化層として Buildkite を載せ、そのうえで 購入 vs レンタル TCO に置いて容量論を証明しましょう。
順番が効きます。まず身分とワークツリー、続いてセットアップとトークン、最後が並行性です。SSH と VNC の照合リスト と同じ土台にもって「ICMP が応答している」だけを祝う状態を終わらせてください。
CI ユーザーとワークルートを準備: たとえば /Users/ci/buildkite とし鍵のみの SSH とし個人デスクトップとは混線させません。
buildkite-agent の導入: macOS では公式インストーラーか Homebrew を推し、バイナリの版がドキュメントと突きあい launchd 下でも動けるか確認します。
buildkite-agent.cfg に記載: token と tags(例 queue=ios,arch=m4)、高速 NVMe 上への build-path。
Hook と環境変数: 環境 Hook で DERIVED_DATA_PATH もしくはビルド別パスを明示し、対話式 rc には依存しません。
最初のヘルスチェック段:xcodebuild -version と sysctl hw.memsize、df -h を記録してエージェント受領ログに残します。
パイプラインで並列とタイムアウト: 重ワークは専用キューへ分離し、巨大な xcresult は合理的な timeout_in_minutes と保持戦略へ。
steps:
- label: ":iphone: iOS compile smoke"
agents:
queue: "ios"
arch: "m4"
command:
- xcodebuild -version
- df -h
- xcodebuild -scheme "App" -configuration Debug -destination "platform=iOS Simulator,name=iPhone 16" build
timeout_in_minutes: 45
Tips: match を運用しているなら Fastlane + CI と合わせ、App Store Connect API 鍵輪転を Buildkite のサイクルに合わせてください。
エージェントを載せ換える際は Canary 前後で同コミットを走らせ、xcodebuild -version とビルド時間分布を比べます。GitHub 相当のキャッシュ層が無いときは Buildkite は厳しい無効化ルールつきローカル永続キャッシュにますます依存します。その境界を切らずにいると「キャッシュヒット」はすぐ「キャッシュ汚染」になります。
広域配置なら名前とタグにリージョンを埋め転送のみの異常へ誤読されないようにパス札を張ります。複数リージョンの構成 と合わせ、遅延と出口課金を早期にモデルへ取り込みます。
典型的な過ちは「Buildkite のキューが緑」と健全な空きディスクなどの余裕を同一視することです。pod install と SPM の解決 とコンパイルの尖値 は別フェーズへ散らばります――ミューテックス資源へはキューを分割するか排他ステップへ。SwiftPM/Pods の記事 と整合させます。
Simulator 主導 UI テストにはコンパイル専用パイプラインと別の並行性モデルが要ります。XCTest と Simulator の分片記事 を参照し、タグまたはプールで境界を切ってください。
アーティファクトとログ保持へ予算線を引きます。Buildkite がログを束ねても巨大 xcresult アップロードは上りリンクを飽和させがちです。プラットフォーム規程で失敗のみ保持・容量上限を明示し、口約束にしないでください。
注意:ディスクが安全水位より下ならキューを詰め込まず最初にスケジューラを止め掃除してください。
Buildkite と他 CI が同一専用機に同居するなら「シフトだけで救う」ことを避け、ユーザーかルートを分割します。クリーニング哲学は ゴールデンイメージと長寿命ノード の章と揃えます。
Elastic CI の収益評価はサブスク料金だけでは足りません。キュー時間の節約分とリリース週の事故回避分として数値を置き納期に結びつけられると説得力が増します。
次の箇条書きを内部向けの基準にし、リポジトリ規模と並列度へ合わせて数値を調整してください。
buildkite-agent --version・xcodebuild -version・CocoaPods 利用時の Ruby/Bundler、ディスク型番まで記録し、構成変更ごとに Canary を流します。オフィス専用の Mac はスリープやジッター、ツールチェーンのドリフトに弱く、Linux は Apple の公式 iOS ツールチェーンをそのままホストできません。Buildkite をキュー/可視化に置き、macOS 実行面を専用で常時電源オン・SSH で必ず辿れる遠隔ノードへ載せれば「パイプラインの単一の真実」が運用契約になります。あとから買い足す機材には電力や部品・オンコールといった隠れコストがつきまとい、仮想化された Xcode スタックは署名・Simulator・隔離の境界でまた破綻します。NodeMini Mac Mini クラウドレンタル は SSH エンドポイントとディスク層、再現可能なエージェント設定が整理されやすく、iOS CI/CD に向くことが多いです。Mac mini のレンタル価格 と Cloud Mac ヘルプセンター を参照してください。
本 Runbook を社内ツールチェーン変更のレベル分けとも連動させ、Xcode パッチ/マイナー/メジャーで承認範囲・Canary の広さ・キャッシュ無効方針が変わる前提を明示してください。
Buildkite はリポジトリ側の pipeline からオーケストレーションとキューを切り離します。Actions は PR イベントと YAML を強く結びますが、macOS ではどちらも Xcode フィンガープリントとディスク境界を揃える必要があります。ハードの段差は Mac mini のレンタル価格 で比較できます。
基本はマシンあたり 1 プロセスで、並列度は limit とキュータグで表現します。複数プロセスを同居させるほど Keychain と DerivedData の競合が増えます。オンボーディングの問い合わせは Cloud Mac ヘルプセンター を参照してください。
SSH 前提の専用 Mac を実行面に据えたまま、単一キューでコストと可視性を揃えたいときに向きます。GitLab MR や Jenkins 承認フローに深く依存しているなら移行コストを踏まえたうえで GitLab Runner と Jenkins + リモート Mac の記事も参照してください。