Cordova iOSビルドの近代化

CocoaPodsとfastlaneによる堅牢なビルド・署名パイプラインの構築

課題: 脆弱なビルドプロセス

手動での証明書管理、一時的な `platforms` ディレクトリへの依存、そして「私のマシンでは動く」問題。これらは、従来のCordova iOS開発におけるCI/CDパイプラインの一般的な失敗要因です。

70%

CI/CDの失敗は署名関連の問題が原因(推定)

10+

手動でのセットアップ手順

構成の不一致によるデバッグ時間

第1部: 宣言的なプロジェクトコアの確立

信頼できる唯一の情報源: `config.xml`

すべての設定は `config.xml` に集約します。アプリケーションID、バージョン、デプロイメントターゲット、そしてCocoaPodsの依存関係も、このファイルで宣言的に管理します。これにより、`cordova platform rm/add` を実行しても、プロジェクト構成は常に一貫性を保ちます。

<platform name="ios">
  <preference name="deployment-target" value="13.0" />
  <plugin name="cordova-plugin-cocoapod-supportx" />
  <pods-config ios-min-version="13.0" use-frameworks="true" />
  <pod name="Alamofire" version="~> 5.0" />
  <pod name="Firebase/Analytics" spec="~> 8.0" />
</platform>

`cordova-plugin-cocoapod-supportx` プラグインが、この宣言を解釈し、`Podfile`を自動生成する鍵となります。

堅牢な構成の要素

堅牢なパイプラインは、宣言的な設定、強力なプラグイン、そして自動化フックの組み合わせで実現されます。

第2部: コード署名の自動化

手動署名 vs `fastlane match`

中央集権的な署名機関: `fastlane match`

`fastlane match`は、証明書とプロビジョニングプロファイルを暗号化し、プライベートGitリポジトリで一元管理します。これにより、チーム内の誰でも、またCIサーバーでも、コマンド一つで安全かつ確実に署名設定を同期できます。

  • `match init`: プロジェクトを初期化。
  • `match appstore`: 証明書とプロファイルを生成・更新し、リポジトリに保存。
  • `match appstore --readonly`: CI/CD環境で安全に認証情報を取得。

重要: プッシュ通知などのケーパビリティを変更した際は、`match appstore --force` でプロファイルを強制的に再生成する必要があります。

第3部: `Fastfile`による自動ビルドパイプライン

これまでの要素を`Fastfile`に統合し、完全自動化されたビルドとデプロイのパイプラインを構築します。`fastlane-plugin-cordova` がCordovaビルドとfastlaneのエコシステムを繋ぐ重要な役割を果たします。

1. 署名同期
match(type: "appstore")
➡️
2. Podsインストール
cocoapods()
➡️
3. Cordovaビルド
cordova(platform: 'ios')
➡️
4. TestFlightへ
pilot()

第4部: 真の堅牢性を求めて

プラットフォームの揮発性を克服: Cordovaフック

`platforms` ディレクトリ内の手動変更は、プラットフォームの再生成時に失われます。`GoogleService-Info.plist` のような構成ファイルのコピーは、`config.xml` で定義されたCordovaフック(例: `after_prepare`)を使ってプログラム的に行うのが唯一の堅牢な方法です。

<hook src="scripts/copy_ios_config.js"
      type="after_prepare" />

バージョンマトリックスの航行

パイプラインは多くのツールに依存します。`Gemfile` (Ruby/fastlane) と `package.json` (Node/Cordova) を用いてバージョンを固定することで、環境差による予期せぬエラーを防ぎます。

一般的なビルドエラーと解決策

エラー/症状 原因 解決戦略
`The 'Pods-App' target overrides...` ビルド設定の競合 ビルド設定に `$(inherited)` フラグを追加。Cordovaフックで修正。
`CocoaPods could not find compatible versions...` Podの要求バージョン > プロジェクト設定 `config.xml` の `deployment-target` を引き上げる。
`No such module 'ModuleName'` (Swift Pod) `use_frameworks!` が未設定 `config.xml` の `` で `use-frameworks="true"` を設定。
`fastlane match` 失敗 / プロファイルが見つからない App IDのケーパビリティ変更によるプロファイルの無効化 `produce enable_services` 後、`match --force` でプロファイルを再生成。