今週はpod updateや一括キャッシュ削除を避け、同じコミットでRunnerが呼び出すRuby、Bundler、CocoaPodsを記録してから、Specs/CDN、認証、ロックファイル、依存ソースの順に切り分けます。ローカルでは成功し、リモートMacのCIだけで失敗するケースに有効な進め方です。
macOS CIを運用し、ローカルとRunnerの環境差を調べるエンジニア向けです。
私有Podを使うチームは、CIアカウントの読み取り権限と資格情報も確認できます。
修正後に同じコミットで再検証し、依存バージョンを不用意に変えずに原因を絞りたい方に適しています。
リモートMac CIでCocoaPodsのインストールに失敗したら、まず境界を確認
最初に確認するのは「どのコマンドが失敗したか」ではなく、「処理のどの段階で止まったか」です。CocoaPodsの起動、依存解決、Specsやソースの取得、Podsプロジェクトの生成、Xcodeでのビルドを別々に扱います。
| 失敗段階 | ログで確認すること | 次の確認先 |
|---|---|---|
| podコマンドの起動 | 実行したコマンド、終了状態、Rubyとpodの参照先 | PATH、Bundler、実行アカウント |
| 依存の解決 | Pod名、要求バージョン、参照したsource | Podfile、Podfile.lock、Specs |
| Specsやソースの取得 | 接続・TLSの記録、応答、取得先 | Runnerの接続性、認証、リポジトリ権限 |
| Pods生成・Xcode連携 | Podsプロジェクトやワークスペースの生成後に出たエラー | CocoaPodsの処理と後続のビルドを分離 |
まずローカルとCIの両方で、コミットID、作業ディレクトリ、実行コマンド、実行アカウントを記録します。作業ディレクトリが違えば、別のPodfileやロックファイルを読み込んでいる可能性があります。
CocoaPodsの公式リポジトリはメンテナンスモードを掲示していますが、それだけで個別のインストール失敗の原因や解決可否は決まりません。症状の分類には公式のトラブルシューティングガイドを参照し、判断は実際のCIログと再現結果に基づけます。
Ruby・Bundler・podの実行環境をローカルと照合
対話型ターミナルで使うRubyと、CIの非対話シェルで使うRubyが同じとは限りません。シェル初期化ファイルが読み込まれない、PATHの優先順位が違う、ジョブの実行アカウントが異なる、といった条件で別のpodが起動することがあります。
| CI内で実行する確認 | 見る情報 | 異なる場合の対応 |
|---|---|---|
which ruby、ruby -v |
Rubyの実体とバージョン | CIのPATHとセットアップ手順を確認 |
gem env |
gemのインストール先 | 実行アカウントと書き込み先を確認 |
which pod、pod --version |
起動するpodとそのバージョン | Bundler経由の実行にそろえる |
bundle exec pod --version |
プロジェクト指定のpodを呼べるか | Gemfileと依存インストールを確認 |
プロジェクトにGemfileとGemfile.lockがあるなら、RubyGemsからグローバルに入れたpodを直接呼ぶのではなく、プロジェクトの依存関係をそろえてbundle exec pod installを実行します。Gemfileを使った管理方法はCocoaPodsのBundlerガイドに、インストールの前提はGetting Startedに記載されています。
CIログに環境変数をそのまま出すのは避けます。認証情報が含まれる可能性があるため、PATHなど必要な項目だけを選んで記録し、秘密値はマスクしてください。
Specs/CDNの失敗は接続とsource設定を分ける
「Specsが見つからない」という表示だけでは、ネットワーク障害とは判断できません。Pod名や要求バージョンが設定と一致していない場合と、Specs取得先への接続・TLS・応答に問題がある場合を分けます。
まずログから、失敗したホスト、接続やTLSのエラー、応答内容、検索されたPod名とバージョンを拾います。次にPodfileのsource指定とRunnerの接続記録を照合します。Podfileのsourceの記述方法はPodfile構文リファレンスで確認できます。
取得元を変更したり、キャッシュを消したりする前に、同じコミットと同じ設定で再実行できる状態を保ちます。複数の変更をまとめて行うと、直ったとしても原因がsource設定なのか接続なのか判別しにくくなります。単発の失敗だけを根拠にCDN全体の障害と結論づけないでください。
私有PodはSpecsとソースの読み取り権限を別々に確認
私有Podで起きる失敗は、Specsリポジトリの参照設定だけでなく、Podのソースを取得する権限でも発生します。CIの実行アカウントが両方にアクセスできるか、分けて確認します。
Podfileが想定するsourceを参照しているかを確認したうえで、CIの資格情報がSpecsの読み取りとソースリポジトリの読み取りに使えるか検証します。私有Specs Repoの構成はCocoaPodsのPrivate Podsガイドを参照してください。
資格情報はCIのシークレット機能から、たとえば$PRIVATE_REPO_TOKENのような占位符として扱います。実際のトークン、鍵、ユーザー名をコマンド例やログに含めないでください。認証エラーに見えても、実際には対象リポジトリへの権限が不足している場合があります。
Podfile.lockを保ち、pod installとpod updateを使い分ける
依存関係の不一致が疑われても、最初にpod updateを実行するのは避けます。pod installは既存のPodfile.lockを利用して依存をそろえるためのコマンドです。一方、pod updateは指定したPodの更新を行い、ロックされた依存バージョンを変更する可能性があります。両者の役割は公式のコマンド比較で確認できます。
確認するのは、Podfile.lockがバージョン管理に含まれているか、CIが正しい作業ディレクトリで実行されているか、実際のコマンドがロックファイルに沿っているかです。依存更新が必要なら、故障対応と混ぜずに別の変更として行い、Podfile.lockの差分をレビューします。
この運用の要点は「失敗を直すために依存を更新する」のではなく、「元の依存状態で失敗を再現し、原因を特定する」ことです。更新後に成功しても、何が問題だったのかが曖昧になるためです。
インストール成功とXcodeビルド成功を別々に受け入れる
podコマンドが終了しても、Xcodeのビルドが成功したとは限りません。依存取得、Podsプロジェクトの生成、ワークスペースへの統合、Xcodeビルドの各結果を分けて確認します。
- [ ] ローカルとRunnerのコミットIDが一致していることを確認します。
- [ ] CIの実行アカウント、作業ディレクトリ、起動コマンドを記録します。
- [ ] Ruby、RubyGems、Bundler、CocoaPodsの参照先をCI内で確認します。
- [ ] Gemfileがある場合は、プロジェクトのBundler環境からpodを起動します。
- [ ] Podfileのsource、Specs取得ログ、私有リポジトリの読み取り権限を別々に確認します。
- [ ] Podfile.lockが使われていることと、CIが想定する場所にあることを確認します。
- [ ] CocoaPodsの処理結果と、その後のXcodeビルドログを分けて保存します。
- [ ] 修正後も同じコミットとロックファイルで再実行し、通過した工程を記録します。
CocoaPodsのコマンドやオプションはコマンドリファレンスで確認できます。インストールが完了しているのにビルドが失敗する場合は、podの取得処理を繰り返すのではなく、Xcode側の最初のエラーへ戻って調べます。
よくある質問
本機では成功するのにRunnerで失敗する場合、最初にそろえる条件は何ですか?
コミットID、作業ディレクトリ、Podfile.lock、実行コマンドを照合します。その後、CIの実行アカウントとPATHを記録してください。環境差を調べずにキャッシュを消すと、再現条件が変わり、原因を追いにくくなります。
Runnerが正しいRubyとpodを使っているか、何を記録すればよいですか?
CIのステップ内でRubyの場所とバージョン、gemの保存先、podの場所とバージョンを確認します。Gemfileがある場合はbundle exec podでも確認し、グローバル環境のpodを誤って起動していないか照合します。対話シェルの結果だけでCIの環境を判断しないことが重要です。
Specs取得失敗が接続と設定のどちらに由来するか、どう切り分けますか?
ログに出た接続・TLSの状況と応答を確認し、Podfileのsource、Pod名、要求バージョンと照らし合わせます。接続に問題があるのか、指定したsourceに対象Specsがないのかを分けてから対処します。一度のエラーだけでCDN全体の状態を断定しないでください。
私有Podを取得できない場合、資格情報をどう扱えばよいですか?
CIの実行アカウントがSpecsリポジトリとPodのソースリポジトリの両方を読み取れるか確認します。トークンや鍵はシークレットから注入し、ログやコマンド例には値を出しません。認証設定だけでなく、リポジトリごとのアクセス権も別々に確かめます。
ローカル端末や自前Runnerだけで運用すると、OSやツールチェーンの管理、稼働状況の維持、CIと開発機の環境差が継続的な負担になります。安定した長期の高負荷運用や物理接続が必要なら自前のMacが適する場合もありますが、CI周期に合わせてmacOS環境を使いたい場合は、リモートMacの利用方法を比較対象にできます。MESHLAUNCHのMac mini利用案内も確認し、必要な期間とツールチェーンに合うかを判断してください。