xcodebuild エクスポート IPA 失敗:2026 リモート Mac どう直す?

xcodebuild エクスポート IPA 失敗:2026 リモート Mac どう直す?

Archiveは成功したのにエクスポート先が空になるなら、同じxcarchiveを固定して、再ビルドではなくExportOptions.plist、署名、Profile、SSH権限を順に検証してください。ArchiveとIPAエクスポートは別段階なので、最後の終了コードだけを見て何度もビルドし直すのは遠回りです。

SSHやCIスクリプトでxcodebuildを実行する独立開発者、リモートMacを常駐のiOSビルド機として運用する担当者、Build・Archive・Export・Uploadを分けて発行障害を短縮したい小規模チーム向けの記事です。

Archive成功とIPA生成を同じ結果と見なさない

脱敏したログでは、次のような状態が典型的な切り分け対象になります。

Archive Succeeded
archivePath: /work/App.xcarchive

Exporting archive...
error: exportArchive ...
exportPath: /work/output
IPA: not found

この場合、Archiveの成果物が存在することは確認できても、IPAが配布可能な状態まで検証されたとは限りません。AppleのXcode分散手順でも、アーカイブ後にテスト配布やリリース用のエクスポートを行う流れが示されています。

AppleのXcode分散手順を基準に、処理を次の4段階へ分けて記録します。

段階 成果物または判定 失敗時に見る場所
Build ビルド済みアプリ ソース、依存関係、Buildログ
Archive .xcarchive Scheme、Configuration、実機向け設定
Export IPAまたは分散用成果物 ExportOptions.plist、署名、Profile、出力権限
Upload App Store Connect側の受付状態 アップロード権限、提出先、処理状態

最初に、Archiveのパス、Xcodeの活動ディレクトリ、出力先、完全なターミナル出力、Distributionログを保存します。作業ディレクトリを毎回変えると、入力ファイルの違いと環境の違いが混ざります。

第一段階:xcarchiveの中身を検収する

まず、対象のxcarchiveが本当にエクスポート可能な入力かを確認します。FinderやOrganizerだけでなく、アーカイブ内のApp本体、拡張、Framework、Info.plist、署名情報が想定どおり存在するかを調べてください。

SchemeとConfigurationが意図したものか、汎用デバイス向けのArchiveかも確認します。シミュレーター向け成果物を混ぜている場合、Archive自体が作成できても配布用エクスポートの入力条件を満たさないことがあります。

App Clip、Notification Extensionなど複数Targetがある場合は、主アプリだけを見てはいけません。各Bundle ID、Capabilities、埋め込まれたコードの関係を一覧化し、Archive内の実際のEntitlementsと突き合わせます。

注意:Archiveを削除して作り直す前に、失敗したxcarchiveとログを別の保存先へ退避してください。削除すると、失敗原因を比較するための入力証拠まで失われます。

OrganizerのValidateまたはDistribute Appと、同じxcarchiveを指定したxcodebuildの結果を比較します。画面操作だけ成功するなら、ArchiveよりもExportOptions.plist、Keychain、セッション権限を優先して疑います。

第二段階:ExportOptions.plistを分散方式ごとに照合する

テスト用デバイスへの分散、App Store Connect向けの提出、その他の分散方式は、同じ設定ファイルを無検証で使い回さないでください。目的が違えば、必要な署名資産、Profile、出力形式の条件も変わります。

最初にXcodeの画面操作で一度成功させ、その実行時に選んだ分散方式、Team、署名管理方式、Profileの割り当てを比較材料にします。次に、対象マシンで次の確認を行います。

xcodebuild -help
xcode-select -p
xcodebuild -exportArchive \
  -archivePath "/path/to/App.xcarchive" \
  -exportOptionsPlist "/path/to/ExportOptions.plist" \
  -exportPath "/path/to/output"

利用可能なキーや値は、対象環境のxcodebuild -helpと現在のApple資料で確認してください。古いブログのテンプレートをそのまま貼り付けると、現在のXcodeが受け付けない設定や、意図しない署名方式が混入します。

確認項目 画面操作で確認する内容 SSH・CIで確認する内容
分散方式 選択した配布先と目的 plistの値が目的と一致するか
Team Xcodeが表示するチーム 実行ユーザーが参照する署名環境
署名管理 自動または手動の選択 plistとProfile指定の整合性
出力先 IPAが作成された場所 親ディレクトリの書き込み権限
実行ログ Organizerの結果 stdout、stderr、Distributionログ

App Store Connectへ送る前のExport成功と、アップロード後に処理が受理されることは別です。アップロード状態はAppleのビルドアップロード状態の説明で確認し、エクスポート失敗とApp Store Connect側の処理遅延を混同しないでください。

第三段階:証明書、秘密鍵、Profileを別々に検証する

証明書ファイルをインポートしただけでは、署名IDが完全に移行されたとは限りません。秘密鍵がKeychainに存在し、対象ユーザーから利用できることまで確認する必要があります。Appleの証明書の種類と用途も参照し、開発用と配布用を取り違えないでください。

次の順で確認すると、いきなり証明書を失効させずに済みます。

  1. Archiveに記録された署名IDと、対象Macの利用可能な署名IDを比較します。
  2. 対応するProvisioning Profileを確認し、Bundle ID、Team、用途、Capabilitiesを照合します。
  3. 主アプリ、拡張、埋め込みFrameworkのEntitlementsを個別に比較します。
  4. Profileの有効性と割り当てを、AppleのProfile管理手順で再確認します。
  5. 自動署名ならアカウント認証と登録状態、手動署名ならplistのProfile指定を確認します。

Profileの削除、証明書の失効、Keychain権限の変更は最後に行います。実施する場合は、現在のProfile、証明書、秘密鍵のバックアップと復旧手順を先に確保し、どのTargetへ影響するかを記録してください。

ローカル成功とSSH失敗をセッション単位で比較する

同じMacでも、画面ログインとSSHでは利用するユーザー、Keychain、Developer Directory、作業パス、テンポラリ領域が一致するとは限りません。したがって「ローカルでIPAが出た」という結果だけでは、無人エクスポートの条件を満たした証拠になりません。

まず同一ユーザーで対話的なSSHセッションを開き、次に同じ環境変数と作業パスで無人タスクを実行します。両方で次をログへ残します。

  • xcode-select -pの結果
  • 実行ユーザーとホームディレクトリ
  • Keychainへ秘密鍵を参照できるか
  • xcarchiveとExportOptions.plistの実体パス
  • 出力先と一時ディレクトリの権限
  • 失敗後も残る標準出力、標準エラー、Distributionログ

AppleのApp Store Connectの役割と権限も確認してください。アカウント側の権限不足と、Mac上の秘密鍵アクセス拒否は別問題です。

経験則:SSHセッションで失敗した直後に再起動やワークスペース削除を行わず、まず失敗した入力、署名情報、ログ、出力ディレクトリを保存してください。証拠を消してから再実行すると、原因が毎回変わって見えます。

FAQ:失敗条件を短く切り分ける

Archive成功後にIPAが出ない場合

Archiveはxcarchiveを作る段階で、IPAエクスポートは分散方式、署名、Profile、Entitlements、出力権限を再確認する段階です。同じxcarchiveを使ってエクスポートだけを再実行し、Archiveの問題か、後段の設定問題かを分けます。

exportArchiveのexit code 70を見た場合

終了コードだけで原因を決めないでください。最初の有効なエラー行、Distributionログ、指定したArchive、plist、署名ID、Profileを一組で保存します。Apple Developer Forumsの個別報告は調査の手掛かりにはなりますが、全環境に共通する規則として扱わないことが重要です。

ExportOptions.plistの確認方法

成功した画面操作の分散方式と、plistの分散方式、Team、署名管理、Profile指定を比較します。使えるキーは対象Macのxcodebuild -helpと現行のApple資料で確認し、過去のテンプレートを無条件に流用しないでください。

SSHだけ失敗する場合

画面ログインとSSHで、ユーザー、Keychain、Developer Directory、作業パス、出力先の権限を比較します。対話シェルで成功しても、無人タスクの環境変数や秘密鍵アクセスが同じとは限りません。ログと中間ファイルを切断後も保存できるか確認します。

無人エクスポートの合格条件

同じxcarchiveを使い、画面操作、SSH対話シェル、無人タスクの順で実行します。署名IDとProfileが一致し、IPAの存在とログ保存を確認でき、タスク再起動後も同じ結果を再現できて初めて、常駐の打包環境として評価できます。

合格判定から次の環境を選ぶ

修正を続けるか、リモートMacの環境を変えるかは、次の判定で決めます。

  • 画面操作もSSHも同じxcarchiveで失敗するなら、Archive、分散方式、署名資産を再検証します。
  • 画面操作は成功し、SSHだけ失敗するなら、Keychain、ユーザー、パス、出力権限を優先します。
  • 一度だけ成功し、再起動後に失敗するなら、秘密鍵の利用条件、Profileの保持、ログ保存を見直します。
  • 同じ入力で成功条件を記録できるなら、リモートMacの利用環境を常駐運用向けに検討できます。
  • 物理的なMacを購入する前に、Mac miniのレンタル構成と比較し、必要な期間だけ検証する方法もあります。

現在の共有マシンや不安定なCI環境を使い続けると、SSHセッションごとのKeychain差異、消えるログ、他作業との権限競合が残ります。反対に、長期間いつも同じ負荷で稼働させる場合や、物理ポートへのアクセスが必要な場合は、自前のMacのほうが適することもあります。

画面操作では成功しているのに無人処理だけ安定しないなら、MacDateのリモートMacで同じxcarchiveを使い、繰り返しエクスポートと再起動後の復旧まで検収してから常駐打包機にするか判断してください。まずは証拠を残せる環境で、IPAが作られる条件を固定することが最短ルートです。