GitHub ActionsでiOSのCI/CDを実現する方法を学びましたが、Appleは公式のCI/CDサービスXcode Cloudも提供しています。
このレシピでは、Appleが提供するXcode Cloudを使って、iOSアプリのビルド、テスト、TestFlightへの配布までを自動化する方法を学びます。GitHub Actionsと違い、Xcode統合で設定でき、Appleのエコシステムとの相性が抜群です。
参考: このレシピはFlutter公式ドキュメントのXcode Cloudガイドに基づいています。
Xcode Cloudは、Appleが提供するクラウドベースの継続的インテグレーション・継続的デリバリー(CI/CD)サービスです。Xcodeに直接統合されており、コードのビルド、テスト、配布を自動化できます。
- Appleエコシステムとの完全統合: 証明書やプロビジョニングプロファイルの管理が自動化され、App Store ConnectやTestFlightとシームレスに連携します。
- macOS環境が不要: Appleのクラウドインフラでビルドが行われるため、ローカルにMacがなくてもiOSアプリの自動ビルドが可能です。
- Xcodeから直接設定: ワークフローの設定がXcodeのGUIから行え、YAMLファイルを書く必要がありません。
- 無料枠あり: 月25時間の無料ビルド時間が提供されており、小規模プロジェクトなら無料で運用できます。(それ以降は従量課金)
| 特徴 | Xcode Cloud | GitHub Actions |
|---|---|---|
| 設定方法 | XcodeのGUIから設定 | YAMLファイルで記述 |
| 証明書管理 | 自動管理 | 手動でSecretsに登録 |
| 料金 | 月25時間無料、以降従量課金 | パブリックリポジトリは無料、プライベートは制限あり |
| 柔軟性 | iOSに特化 | あらゆるプラットフォームに対応 |
| 統合 | App Store Connect統合 | サードパーティツール経由 |
Xcode Cloudを使用するには、以下が必要です。
- Apple Developer Programへの登録(年間99ドル)
- Xcode 15以降がインストールされたMac
- App Store Connectへのアクセス権
- GitHubリポジトリ(またはGitLab、Bitbucket)に管理されているFlutterプロジェクト
- 毎月 25 compute hours が無料で利用可能
- compute hour = クラウドでタスク実行に使用した時間
- 追加が必要な場合は有料プランを購入
Apple Developer Portal → Certificates, Identifiers & Profiles → Identifiers
| 項目 | 設定例 |
|---|---|
| Description | My App |
| Bundle ID | com.example.myapp(Explicit) |
| Capabilities | 必要に応じて選択(後から追加可能) |
App Store Connect → マイ App → 「+」→ 新規 App
| 項目 | 設定例 |
|---|---|
| プラットフォーム | iOS |
| 名前 | My App |
| プライマリ言語 | 日本語 |
| バンドル ID | 先ほど作成した App ID を選択 |
| SKU | myapp(内部管理用、変更不可) |
FlutterプロジェクトのiOSワークスペースをXcodeで開きます。
cd /path/to/your/flutter/project
open ios/Runner.xcworkspace重要: .xcodeproj ではなく .xcworkspace を開いてください(CocoaPods 使用のため)。
Runner ターゲット → Signing & Capabilities タブ
| 項目 | 設定 |
|---|---|
| Automatically manage signing | ✅ チェック |
| Team | 自分のチームを選択 |
| Bundle Identifier | App ID と一致させる |
全ターゲットで設定が必要:
- Runner
- RunnerTests
- RunnerUITests
使用する機能に応じて、ios/Runner/Info.plist に説明を追加:
<!-- カメラ使用(QRスキャンなど) -->
<key>NSCameraUsageDescription</key>
<string>QRコードをスキャンするためにカメラを使用します</string>
<!-- 写真ライブラリ読み取り -->
<key>NSPhotoLibraryUsageDescription</key>
<string>写真を選択するためにライブラリにアクセスします</string>
<!-- 写真ライブラリ保存 -->
<key>NSPhotoLibraryAddUsageDescription</key>
<string>写真を保存するためにライブラリにアクセスします</string>
<!-- 位置情報 -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>現在地を取得するために位置情報を使用します</string>ios/Podfile で iOS バージョンを明示的に指定:
# コメントアウトを解除して設定
platform :ios, '13.0'設定後:
cd ios
pod install --repo-update- Xcodeのメニューバーから
Product > Xcode Cloud > Create Workflow...を選択します。 - 初めて使用する場合、App Store Connectへのサインインを求められます。Apple IDでサインインします。
- 「Start Building」ダイアログが表示されます。
Nextをクリックして進みます。
- ソースコードの場所を聞かれたら、
GitHubを選択します。 - GitHubアカウントへのアクセスを許可します。Xcodeが初めてGitHubに接続する場合、認証画面が表示されます。
- 接続するリポジトリを選択します。
- Xcode Cloudが使用するブランチ(通常は
mainまたはdevelop)を選択します。
Xcode Cloudでは、ワークフローという単位でビルドやテストの自動化を定義します。
接続が完了すると、Xcodeが自動的にデフォルトのワークフローを作成します。
- Xcodeのナビゲーターエリアで
Report Navigator(時計アイコン)を開きます。 - 上部のタブから
Cloudを選択します。 Manage Workflows...をクリックします。
ワークフローの詳細を編集して、ビルド条件や配布設定をカスタマイズします。
- 作成されたワークフローをクリックし、
Edit Workflowを選択します。 - 以下の項目を設定します。
- Xcode Version: 最新の安定版を選択します(例:Xcode 15.x)。
- macOS Version: Xcodeに対応したmacOSバージョンが自動選択されます。
- Environment Variables: 必要に応じて環境変数を追加できます。Flutterの場合は通常不要です。
ビルドをトリガーする条件を設定します。
- Branch Changes: 特定のブランチ(例:
main)にコミットがプッシュされた時 - Pull Request Changes: プルリクエストが作成または更新された時
- Tag Changes: Gitタグがプッシュされた時(リリース専用ワークフローに便利)
- Schedule: 定期的に実行(例:毎晩のビルド)
例えば、リリース用ワークフローでは以下のように設定します。
- Branch or Tag:
Tag Changesを選択 - Tag Pattern:
v*.*.*(例:v1.0.0形式のタグ)
Xcode Cloudが実行するアクションを定義します。
- Archive: リリース用のアーカイブを作成します。これを選択すると、ビルド後にTestFlightに自動配布できます。
- Platform:
iOSを選択 - Scheme:
Runner(Flutterプロジェクトのデフォルト) - Deployment Preparation:
TestFlight and App Storeを選択
- Platform:
- Test: ユニットテストやUIテストを実行します(オプション)。
- Analyze: 静的解析を実行します(オプション)。
ビルド成功後に実行されるアクションを設定します。
- TestFlight Internal Testing: 内部テスターグループに自動配布
- TestFlight External Testing: 外部テスターグループに自動配布(App Reviewが必要)
- Notify: Slackやメールで通知(オプション)
重要: CI スクリプトは Flutter や Xcode Cloud のアップデートにより変更される可能性があります。最新の情報は公式ドキュメントを確認してください:
Xcode CloudはFlutterプロジェクトを直接認識しませんが、カスタムビルドスクリプトを使ってFlutterのビルドプロセスを組み込むことができます。
ios/ci_scripts ディレクトリを作成し、その中に ci_post_clone.sh スクリプトを配置します。このスクリプトは、Xcode Cloudがリポジトリをクローンした後に自動的に実行されます。
mkdir -p ios/ci_scriptsios/ci_scripts/ci_post_clone.sh ファイルを作成し、以下の内容を記述します。
#!/bin/sh
# Fail this script if any subcommand fails.
set -e
# The default execution directory of this script is the ci_scripts directory.
cd $CI_PRIMARY_REPOSITORY_PATH
# ※ Flutter プロジェクトがサブディレクトリにある場合は移動
# cd frontend/myapp
# Install Flutter using git.
git clone https://github.com/flutter/flutter.git --depth 1 -b stable $HOME/flutter
export PATH="$PATH:$HOME/flutter/bin"
# Install Flutter artifacts for iOS (--ios), or macOS (--macos) platforms.
flutter precache --ios
# Install Flutter dependencies.
flutter pub get
# Install CocoaPods using Homebrew.
HOMEBREW_NO_AUTO_UPDATE=1 # disable homebrew's automatic updates.
brew install cocoapods
# Install CocoaPods dependencies.
cd ios && pod install
exit 0注意: このスクリプトは、ビルド時間に約10分追加されます。
スクリプトに実行権限を付与してコミット・プッシュします。
chmod +x ios/ci_scripts/ci_post_clone.sh
git add ios/ci_scripts/
git commit -m "Add Xcode Cloud CI script"
git push設定が完了したら、手動でビルドをトリガーしてテストします。
- Xcodeの
Report Navigator > Cloudタブに戻ります。 - ワークフローを選択し、
Start Buildをクリックします。 - ビルドが開始され、進行状況がXcodeにリアルタイムで表示されます。
ビルドが完了すると、App Store Connectの以下の場所で確認できます。
- TestFlight: ビルドが自動的にアップロードされ、テスターに配布できます。
- Xcode Cloud: ビルドログ、テスト結果、配布状態を確認できます。
設定したトリガー条件(ブランチへのプッシュ、タグのプッシュなど)に従って、Xcode Cloudが自動的にビルドを開始します。
例えば、リリース用ワークフローをタグで設定した場合:
git tag v1.0.0
git push origin v1.0.0このタグプッシュをトリガーに、Xcode Cloudがビルドを開始し、成功すればTestFlightに自動配布されます。
Xcode Cloudの大きなメリットの一つが、証明書とプロビジョニングプロファイルの自動管理です。
- Xcode Cloudは、ビルド時に必要な証明書とプロビジョニングプロファイルを自動的に生成または更新します。
- これらはAppleの管理下に置かれ、GitHub Secretsのように手動で登録する必要はありません。
- 証明書の有効期限が近づくと、自動的に更新されます。
特定の証明書を使用する必要がある場合(例:企業向け配布用の証明書)は、App Store Connectから手動で設定できます。
- App Store Connectにアクセスします。
Xcode Cloudセクションに移動します。Settings > Code Signingで、使用する証明書とプロファイルを指定します。
Xcode Cloud を使わずに手動でアップロードする場合:
- デバイス選択: Any iOS Device (arm64)
- Product → Archive
- Organizer ウィンドウで Archive を選択
- Distribute App をクリック
- TestFlight & App Store または TestFlight Internal Only を選択
- アップロード実行
暗号化に関する質問が表示された場合:
| アプリの状況 | 選択 |
|---|---|
| HTTPS 通信のみ(Firebase、API など) | 「標準的な暗号化アルゴリズム」 |
| 独自の暗号化を実装 | 「独自の暗号化アルゴリズム」 |
| 暗号化なし | 「どれでもない」 |
一般的な Flutter アプリ(Firebase、REST API 使用)は「標準的な暗号化アルゴリズム」を選択し、免除に該当します。
Xcode Cloudは従量課金制ですが、無料枠があります。
- 無料枠: 月25時間のビルド時間
- 有料プラン: 25時間超過後、追加の1時間あたり約$0.95(プランによって異なる)
- 依存関係のキャッシュ: Flutterの依存関係やCocoaPodsのキャッシュを活用することで、ビルド時間を短縮できます。
- 不要なビルドを避ける: ドキュメントの変更など、コードに影響しないコミットではビルドをスキップするように条件を設定します。
# ci_post_clone.shでドキュメント変更時にスキップする例
if git diff --name-only HEAD~1 HEAD | grep -qvE '\.(dart|yaml|swift|m)$'; then
echo "No code changes detected, skipping build"
exit 0
fiApp Store ConnectのXcode Cloud > Usageセクションで、月間のビルド時間や料金を確認できます。
エラー: Signing for "Runner" requires a development team
対処: Xcode → Runner ターゲット → Signing & Capabilities → Team を選択
全ターゲット(Runner, RunnerTests, RunnerUITests)で設定が必要です。
エラー: Module 'mobile_scanner' not found
対処:
flutter clean
flutter pub get
cd ios
rm -rf Pods
rm Podfile.lock
pod install --repo-updateXcode で Product → Clean Build Folder(Cmd + Shift + K)後、再度 Archive。
エラー: Missing purpose string in Info.plist
対処: 使用している機能の説明を ios/Runner/Info.plist に追加(Step 2-3 参照)
エラー: Expected to find project root in current working directory
原因: Flutter プロジェクトがリポジトリのサブディレクトリにある
対処: ci_post_clone.sh でディレクトリを移動:
cd $CI_PRIMARY_REPOSITORY_PATH
cd frontend/myapp # ← サブディレクトリに移動状況: pod install 後に Xcode でダイアログが表示される
対処: Use Version on disk を選択
Xcode Cloudを使うことで、以下が実現できました。
✅ GitHubへのプッシュやタグで自動的にiOSアプリをビルド ✅ 証明書とプロビジョニングプロファイルの自動管理 ✅ TestFlightへの自動配布で、テスターにすぐに新しいビルドを届けられる ✅ XcodeのGUIから直接設定でき、YAMLファイルを書く必要がない
Xcode CloudはAppleエコシステムとの統合に優れており、特にiOS専用のプロジェクトや、証明書管理の複雑さを避けたい場合に最適です。
一方、AndroidとiOSを同じCI/CDで管理したい場合や、より高度なカスタマイズが必要な場合は、GitHub Actionsの方が適している場合もあります。プロジェクトのニーズに応じて、最適なCI/CDツールを選択しましょう!
- Apple Developer Program 登録済み
- App Store Connect でアプリ登録済み
- Bundle ID 登録済み
- Xcode で Signing & Capabilities 設定済み
- Info.plist に必要な説明を追加済み
- Podfile で iOS バージョン指定済み
-
ci_post_clone.sh作成・コミット済み
- Xcode からワークフロー作成済み
- 初回ビルド成功
- Archive 作成成功
- App Store Connect にアップロード成功
- テスターに招待送信済み
- Flutter Continuous Delivery - CI/CD 公式ガイド(必読)
- Flutter iOS デプロイ
- Requirements for using Xcode Cloud - 必要要件
- Get started with Xcode Cloud - 概要と料金
- Writing custom build scripts - カスタムスクリプト
ここからは、複数人のチームで Xcode Cloud を運用する場合に必要な権限設定やワークフローについて説明します。
重要な公式ドキュメント: Configuring Xcode Cloud for your team - 必読
注意: App Store Connect と Apple Developer Program は別々のシステムです。両方でアクセス権が必要です。
| サービス | 役割 | 必要な権限・条件 |
|---|---|---|
| Apple Developer Program | - | メンバーシップ登録必須(年額 $99) |
| App Store Connect | Account Holder | 全権限。契約締結、メンバーシップ更新が可能 |
| App Store Connect | Admin | ワークフロー作成、アプリ登録、ユーザー管理が可能 |
| App Store Connect | App Manager | アプリ登録、TestFlight 管理が可能 |
| App Store Connect | Developer | Create Apps permission があればアプリ登録可能 |
| App Store Connect | Marketing | Create Apps permission があればアプリ登録可能 |
公式ドキュメント(Get started with Xcode Cloud)より:
ワークフローの設定は、Account Holder、Admin、または App Manager が行えます。また、App Store Connect で Create Apps permission を付与された Developer または Marketing 役割のチームメンバーも設定可能です。
| 登録タイプ | App Store Connect | Apple Developer Program(Certificates等) | アプリ配布可能な役割 |
|---|---|---|---|
| Individual | メンバー追加可能(最大50人) | 追加不可 | Account Holder のみ |
| Organization | メンバー追加可能(無制限) | メンバー追加可能 | Account Holder, Admin, App Manager |
Individual 登録の制限:
- App Store Connect にはメンバーを追加できる
- ただし、追加されたメンバーは Xcode のチームには表示されない(Certificates, Identifiers & Profiles にアクセス不可)
- アプリの配布は Account Holder のみ
チーム開発で Xcode の署名機能を共有する必要がある場合は、Organization への変更を検討してください。
公式ドキュメント:
| 権限 | Xcode Cloud 初期設定 | コード Push | ビルド結果閲覧 |
|---|---|---|---|
| Admin | ✅ | ✅ | ✅ |
| Write | ❌ | ✅ | ✅ |
| Read | ❌ | ❌ | ✅ |
重要: Xcode Cloud の初期設定には GitHub Admin 権限が必要です。Webhook 設定と Apple との連携認証のためです。
公式ドキュメントより:
リポジトリの管理者が Apple プラットフォーム開発の専門知識を持っていない場合でも、その管理者に Xcode Cloud 用のプロジェクト設定を行わせ、最初のビルドが失敗しても問題ありません。
つまり:
- GitHub Admin が Mac + Xcode で初期接続のみ行う
- 最初のビルドは失敗しても OK
- その後、iOS 開発者がワークフローを修正
App Store Connect でチームメンバーのソースコードアクセスを管理できます:
App Store Connect → Users and Access → Xcode Cloud タブ
ここで各メンバーに対して:
- どのリポジトリにアクセスできるか
- ビルドの閲覧・実行権限
を設定できます。
公式ドキュメント: Configuring Xcode Cloud for your team
- Xcode プロジェクト設定
- Archive 作成・アップロード
- TestFlight でのテスト管理
- Xcode Cloud 初期設定時の認証許可
- Mac + Xcode が必要(最初のビルド失敗は OK)
- Flutter コードの開発
flutter pub get/flutter build iosci_post_clone.shの修正
- App Store Connect でのアプリ登録
- TestFlight テスター管理
- メタデータ・スクリーンショット管理
- Apple Developer Program に Organization で登録済み(チーム共有が必要な場合)
- App Store Connect でチームメンバーに適切な役割を付与済み
- GitHub リポジトリで Admin 権限を持つメンバーがいる
- GitHub Admin 権限を持つメンバーが初期接続を実施
- Xcode からワークフロー作成済み
- App Store Connect でソースコードアクセスを設定済み
- 役割別の作業範囲をチームで共有済み
- ビルド失敗時の対応フローを決定済み
- Configuring Xcode Cloud for your team - チーム設定の公式ガイド
- App Store Connect Role Permissions - 権限一覧表
- Apple Developer Program Roles - 役割の詳細
- Overview of accounts and roles - アカウント管理