GitHub公式リファレンスでは、self-hosted runnerのJob割り当てはラベル、Runner Group、オンライン状態、空き状態を条件に行われます。Runnerのルーティング条件に照らすと、GitHub Actions Mac Runner がずっと待機中でも、最初にMacを増やす判断は適切ではありません。今週は、ルーティング、占有、macOSサービスの順に証拠を固定し、修正後も実キューが残る場合だけ遠隔Macの増設へ進めます。
このガイドは、GitHub Actionsで自托管のMacを使ってXcodeビルドを実行している開発者向けです。Runnerのラベル、Runner Group、リポジトリの利用範囲、常駐サービスを管理するDevOps担当者や、既存ノードを修復・再登録・拡張のどれにするか判断する責任者にも適しています。
最初に排除するべき4種類の「待機中」
Runner管理画面がIdleでも、対象JobがMac Runnerを待っているとは限りません。ワークフローの前段Job、承認、並行実行制限、Runnerのルーティングは別の待機状態なので、まず実行履歴とJob詳細の注釈を確認します。
| 状態 | 主な証拠 | 先に行う確認 |
|---|---|---|
| 前段条件待ち | needsや条件式でJobが開始されていない | 前段Jobの成功、失敗、スキップ状態 |
| 承認待ち | Environmentや手動承認に関する表示 | 承認者、保護ルール、対象環境 |
| 並行実行待ち | 同じグループの実行が制限されている | concurrency設定と実行中Job |
| Runner待ち | Jobがruns-on条件を満たす実行機を待っている | ラベル、Group、オンライン・空き状態 |
同じタイミングで、ワークフローのコミット、対象Jobのruns-on、Runnerのラベル、Group、アクセス設定を保存します。先にYAMLや権限を変更すると、元の故障経路が消えてしまいます。
GitHub Actionsの並行実行制御は、公式のconcurrency仕様でも独立した設定として扱われています。したがって、RunnerがIdleなのにJobが動かない場合も、Runnerだけを再起動する前に並行実行設定を除外してください。
ラベルの一致と実行経路を分けて検証する
runs-on に複数のラベルを指定した場合、条件は「いずれか」ではなく、指定されたラベルの組み合わせです。ラベルの公式説明に従い、OS、CPUアーキテクチャ、Xcodeや署名環境などの独自ラベルを一つずつ照合します。
| 確認対象 | よくある不一致 | 低リスクな修正 |
|---|---|---|
| OSラベル | macOSとmacosのような表記差 |
実際の登録ラベルを管理画面から転記 |
| アーキテクチャ | Apple Silicon用ラベルが再登録後に欠落 | ノードの用途を確認して必要なラベルだけ復元 |
| ツールチェーン | Xcodeの世代や署名環境ラベルが古い | 本番YAMLを直す前に診断Jobで確認 |
| 独自ラベル | ノード削除・再登録時に消失 | 変更履歴と登録直後のラベルを比較 |
まず機密情報を含まない最小Jobで、ルーティングだけを確認します。
name: runner-route-check
on:
workflow_dispatch:
jobs:
route:
runs-on: [self-hosted, macos, arm64]
steps:
- name: Show runner context
run: |
uname -a
echo "runner=${RUNNER_NAME}"
echo "os=${RUNNER_OS}"
echo "arch=${RUNNER_ARCH}"
このJobが開始しない場合は、Xcode、依存関係、署名証明書を調べても原因には近づきません。runs-onで実行Runnerを選ぶ仕様と実際の登録ラベルを並べ、条件を一つずつ外した診断用ブランチを用意します。ただし、本番Jobを長期間 self-hosted だけに変更するのは避けてください。別用途のMacへ誤配車される危険があります。
Runner Groupの権限はラベル一致後にも残る
ラベルが一致していても、対象リポジトリにRunner Groupの利用権限がなければJobは割り当てられません。組織レベルで登録されたMacでは、Runnerの所属階層、Group名、許可されたリポジトリ一覧を別々に確認します。
| ルーティング層 | 見る項目 | 記録する証拠 |
|---|---|---|
| Runner本体 | 所属組織・Enterprise、オンライン状態 | 管理画面の状態と登録名 |
| Runner Group | Groupの階層、対象リポジトリ許可 | 設定画面の許可範囲 |
| ワークフロー | runs-onとGroup指定 |
対象コミットのYAML |
| リポジトリ | 組織設定との継承関係 | 利用可能Runnerの表示 |
Runner Groupのアクセス管理では、Groupを利用できるリポジトリの範囲を管理します。ラベルを追加するだけではこの許可は変わりません。
権限変更の前に、秘密情報を使わない診断Jobを対象リポジトリから実行し、変更前後で見えるRunnerとJobの状態を記録します。Group権限を広げる場合は、組織全体へ無制限に公開せず、検証用リポジトリを明示的に指定してください。
本当に空きがない場合だけ容量を検討する
条件に合うRunnerがすべてBusyなら、まず実行中Jobの一覧、プロセス、作業ディレクトリのロックを確認します。Xcodeのビルド、Simulatorテスト、署名・配布、長時間の統合テストは、同じMacを実質的に独占することがあります。
ただし、Jobが終了したのにRunnerがBusyのままなら、容量不足ではなく後処理の停止やRunnerプロセスの異常かもしれません。ログ、プロセス、最後にJobを受け取った時刻を保存してから、対象ノードだけを保守します。
ps aux | grep -i Runner
launchctl print system | grep -i runner
上記の確認結果だけでサービス名や実行ユーザーを推測してはいけません。環境固有のlaunchd定義を確認し、停止や削除を行う場合はplist、作業ディレクトリ、再登録情報を先に退避します。
注意:Runnerを削除したり登録トークンを無効化したりすると、復旧前に既存Jobの実行経路が失われます。削除は登録状態の破損をログで確認した後に限定し、再登録手順と戻し先のラベルを記録してから実施してください。
SSH接続ではなくmacOSサービスの受け取り能力を見る
SSHでMacへ接続できても、RunnerサービスがGitHubへ接続し、Jobを受け取れるとは限りません。macOS Runnerの監視・トラブルシューティングを参照し、管理画面、診断ログ、ネットワーク、launchd、サービスアカウントを同じ時系列で確認します。
特に見落としやすいのは、再起動後にログインセッションへ依存している構成、サービスユーザーが作業ディレクトリへ書き込めない状態、自動更新後にプロセスが復帰していない状態です。画面がIdleであっても、直近の接続ログとJob受領ログがなければ「正常」とは判定しません。
サービスの再インストールやRunnerの再登録は最後の手段です。実施する場合は、既存のラベル、Group、作業ディレクトリ、診断ログを保存し、削除が必要なら公式のRunner削除手順に沿って復元経路を確保します。
FAQ:排隊状態を原因別に切り分ける
自托管RunnerがオンラインなのにJobを受け取らない理由
オンライン表示は、Runnerが登録されていることを示すだけです。ラベル、Runner Groupの権限、実行中プロセス、ネットワーク接続、macOSサービスの受領状態を別々に確認し、最小Jobがどの段階で止まるかを記録します。
runs-onが一致しているのにqueuedが続く場合
複数ラベルはすべて一致する必要があります。また、ラベル一致後にRunner Groupの利用許可で拒否されることもあります。実際のRunnerラベルとGroup設定を保存し、Xcode処理を含まない診断Jobで経路だけを確認します。
Idle表示でもワークフローが開始しない場合
並行実行制限や承認待ちが、Runner待ちに見えている可能性があります。Job詳細の前段条件、Environment承認、concurrency設定を先に確認し、それらに該当しなければラベルとサービスログへ進みます。
Runner Groupを特定リポジトリで使えない場合
Groupの許可範囲は、Runnerのラベルとは別のアクセス制御です。組織設定で対象リポジトリが明示的に許可されているか、Groupの階層を越えていないかを確認し、無関係なリポジトリへ権限を広げない形で検証します。
遠隔MacのRunnerを追加する判断基準
修正後も、条件に合うRunnerが実際にBusyであり、Jobが安定して待機し、サービス障害やGroup拒否がない場合に限って追加を検討します。タスクをビルド、Simulator、配布などに分け、どの待機が容量不足なのかを確認してから増設します。
修復・再登録・増設を決める復測マトリクス
次の順序で復測すると、ルーティング故障、ノード故障、容量不足を混同しにくくなります。
| 復測 | 成功条件 | 判定 |
|---|---|---|
| 最小コマンドJob | 対象ラベルとGroupで開始し、Runner名を取得 | ルーティング確認 |
| 実Xcodeビルド | ビルド、署名、成果物保存まで完了 | ノード実行確認 |
| 本番近似Job | キャッシュ、Simulator、成果物回収まで再現 | 運用復旧確認 |
復測前には、保守対象を一時的に本番キューから外し、診断用のラベルを本番ラベルと混ぜないようにします。最小Jobだけが成功してXcode Jobが止まるなら、Runner経路ではなくツールチェーンや作業ディレクトリを調べます。
逆に、最小Jobから開始しないなら、Xcodeを再インストールしても改善しません。ラベルとGroupを修正してもサービスログに受領記録がなければ、macOS側のRunnerプロセスを修復します。三種類の復測が通り、それでも適格なノードが継続的にBusyなら、タスク分池、実行時間の分散、遠隔Mac容量の追加を比較します。
自社でMacを常時確保する場合は、購入前にMac miniの運用方案と、実行場所を含むNodeMiniのMac環境を比較すると、物理機の保守範囲と遠隔ノードの切り分けがしやすくなります。
今週実施する確認チェックリスト
- [ ] Job詳細で、前段条件、承認、concurrency、Runner待ちを区別した
- [ ] 変更前のYAML、runs-on、Runnerラベル、Runner Groupを保存した
- [ ] OS、CPU、ツールチェーン、独自ラベルを実登録値と照合した
- [ ] 対象リポジトリがRunner Groupの利用範囲に含まれることを確認した
- [ ] 実行中Job、異常プロセス、作業ディレクトリのロックを確認した
- [ ] macOSの診断ログ、ネットワーク、launchd、サービスユーザーを確認した
- [ ] 最小コマンドJob、実Xcodeビルド、本番近似Jobを順番に復測した
- [ ] 再登録や削除の前に、ラベル、Group、作業ディレクトリ、復元手順を保存した
- [ ] 容量追加の判断を、ルーティングとサービス復旧後に行った
Linuxのビルドノードを使い続ける方法は、XcodeやApple SDKを必要とするJobを処理できず、Macを手元で運用する方法は、電源・スリープ・回線・保守の影響を受けます。購入したMac miniは初期費用と物理管理が発生し、既存ノードを無理に共有すると、ビルドとSimulatorテストの相互干渉も避けにくくなります。
そのため、原因を切り分けた後に隔離した検証ノードや予備のビルド能力が必要なら、NodeMiniの遠隔Macを同じWorkflowで受け入れ確認する方法が現実的です。まず短いレンタル期間でラベル、Group、サービス復旧、成果物回収まで検証し、安定した長期負荷だけを自社保有構成へ残すと、増設理由を監査可能な形で説明できます。