GitHub公式では、self-hosted runnerをリポジトリ、組織、Enterpriseの単位で登録できます。Runner追加の公式手順に沿って登録すれば、GitHub Actions iOS ビルドをリモート Macへ振り分けられます。ただし、登録だけで本番運用を始めるのは危険です。Xcodeの固定、署名情報の隔離、Archive・書き出し・アップロードの個別確認、再起動後の復旧まで通過して初めて、常駐ビルド機として扱えます。
この内容は、GitHubでソース管理を行い、自動ビルドと公開を進めたい独立開発者向けです。
手元にMacがなく、リモートのmacOS環境を常用Runnerへ変えたいWindows・Linux開発者や、Xcodeと署名情報を管理したい小規模チームにも適しています。
GitHub Actions iOS ビルドの合格条件
最初に、成功を「ジョブが緑色になったこと」と定義しないことが重要です。iOSの配布では、ソース取得とコンパイル、Archive作成、署名付き書き出し、App Store Connectへの転送、Apple側の処理が別の状態だからです。
可用性の確認
リモート Macには、対象のXcodeとmacOSの組み合わせ、依存関係を取得できるストレージ、安定した接続、継続稼働できる電源環境が必要です。Xcodeの対応OSやSDK、App Store Connectへのアップロード条件は変わり得るため、使用する版を決める前にAppleのXcodeシステム要件を確認します。
対話式にターミナルを開いてRunnerを起動する方法は、セッション切断やログアウトで停止する可能性があります。GitHubのRunnerサービス設定を使い、ホスト再起動後にもプロセスが起動する構成にします。
ジョブのルーティング設計
ラベルの組み合わせ
GitHub Actionsは、Runnerに付いたラベルとワークフローのruns-on条件が一致した場合にジョブを割り当てます。標準ラベルだけでなく、公開用と検証用を区別する自作ラベルを付けると、誤って別の環境へ署名処理を送るリスクを抑えられます。ラベルによるルーティングの仕様を確認し、条件を実際のジョブで検証します。
jobs:
release:
runs-on: [self-hosted, macOS, ARM64, ios-release]
steps:
- uses: actions/checkout@v4
- name: Xcodeの選択
run: sudo xcode-select -s "<XCODE_DEVELOPER_PATH>"
上のパス、ラベル名、アクションの版は環境に合わせて置き換えます。リポジトリ名、Bundle ID、Team ID、証明書名、パスワード、API Key、Runner Tokenを実値で記載してはいけません。
| ルーティング条件 | 適した用途 | 判断ポイント |
|---|---|---|
| macOSのみ | 一般的な検証ビルド | iOS用ジョブ以外が混在しないか確認します |
| macOS+ARM64 | Apple Siliconを前提とする依存関係 | ネイティブバイナリの対応を確認します |
| macOS+用途ラベル | 本番ArchiveとTestFlight公開 | 公開権限を持つRunnerを限定します |
| 一致するRunnerなし | ジョブは待機状態 | タイムアウト、通知、オンライン状態を確認します |
Runnerが一致しない場合、ジョブは直ちに別OSへ切り替わるのではなく、実行可能なRunnerを待ちます。待機が長引いたときに、ラベル誤り、サービス停止、アクセス範囲の設定を調べられるよう、GitHubの監視・トラブルシューティングを基準に記録を残します。
Xcodeと依存関係の固定
複数のXcodeが入ったMacでは、コマンドが意図しないDeveloperディレクトリを参照することがあります。ワークフロー開始時に選択先を明示し、xcodebuild -versionなどの出力をログへ残します。ログには秘密情報が含まれないよう、環境変数や認証ファイルの内容を表示しません。
依存関係はSwift Package Manager、CocoaPodsなど、採用している方式のロックファイルをコミットします。まず署名材料を使わない最小ビルドを実行し、チェックアウト、依存関係の復元、Scheme指定、コンパイルが同じRunnerで再現できることを確かめます。ここで失敗する場合は、証明書を追加しても原因を隠すだけです。
| 検証段階 | 記録する結果 | 不合格時の切り分け |
|---|---|---|
| ソース復元 | checkoutと依存関係取得 | ロックファイル、権限、接続 |
| コンパイル | SchemeとSDKを指定したビルド | Xcode、SDK、ネイティブ依存 |
| Archive | .xcarchiveの生成 |
Release設定、Bundle ID、署名設定 |
| 書き出し | IPAと関連成果物 | Provisioning Profile、証明書 |
| アップロード | App Store Connectへの転送 | 認証情報、SDK要件、通信 |
| Apple側処理 | ビルドが利用可能な状態か | 管理画面の処理状態、警告 |
Appleのアプリのアーカイブと配布に関する説明に照らし、Archive生成とアップロードを同じ成功扱いにしないでください。IPAが作成されても、App Store Connect側の処理が完了していなければTestFlightで配布できない場合があります。
署名情報とアクセス境界
iOS開発者証明書、秘密鍵、Provisioning Profile、App Store Connect用の認証情報は役割が異なります。Appleの証明書概要を確認し、単一のAPI Keyだけでコード署名まで代替できると考えないことが大切です。
GitHub Secretsへ暗号化して保存した値は、ジョブ実行時だけ一時ファイルまたは一時Keychainへ取り込みます。終了後はKeychain、Profile、生成した認証ファイルを削除し、ログのマスキングを確認します。実際の証明書や秘密鍵をリポジトリへ置かないことは、漏えい後の影響範囲を小さくする基本策です。
自前Runnerは、実行するコードがホストへアクセスできる点で、GitHubホストRunnerとは異なるリスクがあります。特に公開リポジトリや外部コントリビューターのコードを、本番署名用Runnerで無条件に実行しないでください。GitHubの自前Runner向けセキュリティ警告に従い、私有リポジトリ、許可ブランチ、公開用ワークフローを分離します。
実装から公開までの検証手順
以下は、単なる登録手順ではなく、常駐Runnerとして採用する前の確認順序です。
- Runner登録:リポジトリまたは組織の設定から登録し、
self-hosted、macOS、必要ならARM64と用途ラベルを付けます。トークンは画面やログへ残しません。 - サービス化:対話式の起動を停止し、macOSサービスとして登録します。再起動後にRunnerがオンラインになるかを確認します。
- ツールチェーン確認:XcodeのDeveloperディレクトリ、Scheme、SDK、依存関係のロックファイルを指定し、署名なしの最小ビルドを実行します。
- アクセス制限:公開用Runnerへ接続できるリポジトリ、ブランチ、ワークフローを絞ります。Pull Requestの外部コードを同じ権限で動かしません。
- 署名材料の投入:Secretsから一時KeychainとProvisioning Profileを生成し、実行後に削除します。証明書名やTeam IDはサンプル内で
<TEAM_ID>のように伏せます。 - Archive確認:コンパイル成功後、指定SchemeでArchiveを作成し、
.xcarchiveの保存先と保持期間を決めます。 - 書き出しと転送:署名付きIPAを書き出し、App Store Connectへ送ります。転送成功とApple側の処理完了を別々に記録します。
- 障害復旧:ホスト再起動、Runner更新、キャッシュ破損、ディスク増加、ビルド中断を想定し、再登録、アクセス撤回、秘密情報の交換手順を文書化します。
ログ、Archive、デバッグシンボルは無期限に残すのではなく、チームの調査要件に合わせて保管範囲を決めます。特に署名用ファイルや一時Keychainを成果物としてアップロードしないよう、成果物の対象パスを明示してください。
採用判断のチェックリスト
次の項目に未確認が残る場合、常駐の本番Runnerではなく、検証用の短期環境として扱う判断が安全です。
- [ ] 現在のXcodeとmacOSの対応条件をApple公式情報で確認した
- [ ] Runnerがサービスとして起動し、再起動後もジョブを受け取った
- [ ] 本番公開用ラベルと検証用ラベルを分離した
- [ ] 外部コードが署名用Runnerへ到達しない
- [ ] 署名情報をSecretsから一時的に扱い、終了後に削除した
- [ ] コンパイル、Archive、書き出し、アップロードを個別に記録した
- [ ] App Store Connect側の処理状態まで確認した
- [ ] 失敗時にツールチェーン、署名、転送、Apple側処理のどこかを判定できる
- [ ] Runnerの再登録とアクセス撤回を実行できる
自前Runnerの状態だけでなく、ジョブがどのラベルへ送られ、どのXcodeを使い、どの成果物を生成したかを追跡できることが、運用判断の基準になります。
よくある確認事項
リモート MacでiOSアプリをビルドする構成は作れますか?
GitHub ActionsのジョブをmacOSのself-hosted runnerへ割り当てれば、リモート MacでXcodeを使ったビルドを実行できます。ただし、Runner登録は入口にすぎません。ラベル、Xcodeの選択、署名情報、Archive、書き出し、App Store Connect側の処理を個別に検証して、初めて公開用途に適した構成になります。
Xcodeの版が複数あるMacで誤動作を防ぐにはどうしますか?
ワークフローの開始時にDeveloperディレクトリを指定し、選択されたXcodeの版をログへ記録します。macOSとの互換性やSDKのアップロード条件はAppleのシステム要件で確認し、ホストにある既定の選択状態へ依存しないことが重要です。変更後は署名なしビルドから再実行します。
署名証明書をリモート環境へ置くときの安全策は何ですか?
証明書、秘密鍵、Provisioning Profileはリポジトリへ置かず、GitHub Secretsからジョブ実行時だけ取り込みます。一時Keychainを使い、ログのマスキングとジョブ終了後の削除を確認します。さらに、本番Runnerを私有リポジトリや許可済みブランチへ限定し、信頼できないコードと署名処理を分離します。
Macが再起動した後、Runnerがオンラインになったか確認できますか?
macOSサービスとして登録し、ホスト再起動後にRunnerサービスの状態、GitHub上のオンライン表示、ジョブ受信の三つを確認します。プロセスだけが起動していても、ラベルやアクセス範囲が誤っていればジョブは処理されません。サービスログとGitHubのRunner状態を突き合わせて判断します。
TestFlightへ送ったのにビルドが表示されない場合はどうしますか?
転送コマンドが成功したかだけでなく、Apple側でビルド処理が完了したかを確認します。Archive、IPA、認証情報、アップロード結果を別々に保存し、どの段階で止まったかを切り分けます。対象SDKやXcodeの条件に問題がないかも、Appleのアップロード要件と照合します。
GitHub Actions iOS ビルドを常用する場合、現在の構成を「ソース取得から公開まで一つの処理」と見なさないことが重要です。手元のワークフローを作成した後は、まず短期のリモート Macで実プロジェクトのArchive、署名付き書き出し、TestFlight転送を試し、再起動復旧と失敗箇所の特定まで確認します。
既存のWindows・Linux環境や一時的なCI環境では、macOS専用のXcodeを維持できないこと、署名用ホストを常時稼働させにくいこと、再起動後のRunner復旧を自分で設計する必要があることが負担になります。こうした条件で物理Macを購入せず、必要な期間だけ実機のmacOS環境を使いたい場合は、RUVCLOUDのMacレンタル案内や利用プランを確認できます。常時の大規模ビルドや物理デバイス接続が必要なケースでは自前機の方が適するため、まずこのチェックリストを通過できるかで採用を決めるのが現実的です。