Fastlane + GitHub ActionsでFlutter iOS/Androidのビルド、コード署名、App Store配信を自動化

Flutterでのアプリ開発は楽しいものですが、完成したアプリをApp StoreやGoogle Play Storeに配信するプロセスは、しばしば開発者にとって大きなストレスとなります。証明書の管理、プロビジョニングプロファイルの紐付け、ビルドバージョンのバンプ、そしてストアへのアップロードまで、手作業で行うべきことが多すぎるからです。
このガイドでは、FastlaneとGitHub Actionsを組み合わせて、FlutterアプリのiOSおよびAndroidのビルド、コード署名、そしてストア配信のプロセスを完全に自動化する構築方法を取り上げます。
なぜCI/CDの自動化が必要なのか?
手動の配信プロセスでは、次のような問題が頻繁に発生します。
- ヒューマンエラー: 証明書を間違えて紐付けたり、ビルドバージョンを上げるのを忘れるミス。
- 時間の無駄: ローカルマシンでアーカイブ(Archive)し、ストアにアップロードされるまで待機しなければならない時間。
- 依存性: 特定の開発者のローカル環境(特にMac)とアカウントに依存する配信プロセス。
GitHub ActionsとFastlaneを使用すれば、コードをmainまたはreleaseブランチにプッシュするだけで、これらすべてのプロセスをクラウド上で安全に処理できます。
1. Fastlaneの設定(ローカル)
まず、FlutterプロジェクトのandroidとiosディレクトリそれぞれでFastlaneを初期化する必要があります。
Android Fastlaneの初期化
cd android
fastlane init
初期化プロセスで、パッケージ名とJSONシークレットキーのパスを尋ねられます。Google Play Consoleで発行されたサービスアカウント(Service Account)のJSONキーが必要です。
android/fastlane/Fastfileの例:
default_platform(:android)
platform :android do
desc "Submit a new Beta Build to Crashlytics"
lane :beta do
gradle(task: "clean bundleRelease")
upload_to_play_store(track: 'beta')
end
end
iOS Fastlaneの初期化
iOSの配信は、証明書とプロビジョニングプロファイルの管理が重要です。Fastlaneのmatchを使用すると、このプロセスをGitリポジトリを通じてチームメンバーと安全に共有し、CI/CDで簡単に読み込むことができます。
cd ios
fastlane init
fastlane match init
ios/fastlane/Fastfileの例:
default_platform(:ios)
platform :ios do
desc "Push a new beta build to TestFlight"
lane :beta do
setup_ci
match(type: "appstore", readonly: true)
# FlutterのビルドはGitHub Actionsで行うため、Fastlaneでは既にビルドされたアプリを処理します。
build_app(workspace: "Runner.xcworkspace", scheme: "Runner")
upload_to_testflight
end
end
[!IMPORTANT] iOSのコード署名をCI環境で実行するには、Fastlane Matchの使用を強く推奨します。ローカルから証明書をエクスポートしてCIにアップロードするよりも、はるかに安全で管理が簡単です。
2. GitHub Actions ワークフローの構成
次に、リポジトリの最上位に.github/workflows/deploy.ymlファイルを作成します。
ワークフローの基本構造と環境変数
GitHub Secretsに次の値を事前に保存しておく必要があります。
MATCH_PASSWORD: Fastlane Match 復号化パスワードMATCH_GIT_BASIC_AUTHORIZATION: Matchリポジトリへのアクセス用PAT(Personal Access Token)APP_STORE_CONNECT_API_KEY_KEY_ID: App Store Connect API Key IDAPP_STORE_CONNECT_API_KEY_ISSUER_ID: App Store Connect API Issuer IDAPP_STORE_CONNECT_API_KEY_KEY: App Store Connect API Key(.p8の内容)PLAY_STORE_CONFIG_JSON: Google Play サービスアカウントのJSONの内容
ワークフロー全体のスクリプト
name: Deploy to App Store & Google Play
on:
push:
tags:
- 'v*' # v1.0.0 のようなタグがプッシュされたときに実行
jobs:
build-and-deploy:
runs-on: macos-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '17'
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
channel: 'stable'
- name: Install dependencies
run: flutter pub get
# --- iOS 配信パイプライン ---
- name: Setup Ruby for Fastlane
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
bundler-cache: true
working-directory: ios
- name: Decode App Store Connect API Key
run: |
mkdir -p ~/.appstoreconnect/private_keys/
echo "${{ secrets.APP_STORE_CONNECT_API_KEY_KEY }}" > ~/.appstoreconnect/private_keys/AuthKey_${{ secrets.APP_STORE_CONNECT_API_KEY_KEY_ID }}.p8
- name: Build iOS App
run: flutter build ipa --release --export-options-plist=ios/ExportOptions.plist
- name: Deploy iOS to TestFlight
working-directory: ios
env:
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
MATCH_GIT_BASIC_AUTHORIZATION: ${{ secrets.MATCH_GIT_BASIC_AUTHORIZATION }}
run: bundle exec fastlane beta
# --- Android 配信パイプライン ---
- name: Setup Ruby for Fastlane (Android)
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
bundler-cache: true
working-directory: android
- name: Decode Play Store JSON
run: echo "${{ secrets.PLAY_STORE_CONFIG_JSON }}" > android/play_store_config.json
- name: Build Android App
run: flutter build appbundle --release
- name: Deploy Android to Play Store
working-directory: android
run: bundle exec fastlane beta
重要な考慮事項
- Mac環境の選択: iOSビルドには、必ず
macos-latestランナー(Runner)を使用する必要があります。(Linuxランナーよりも課金率が高い点に注意してください。) - Flutterビルドの最適化: iOSの場合、
flutter build ipaコマンドにアーカイブまでのすべてを処理させることができます。この場合、Fastlaneはアップロードの役割のみを担当するように構成する方が、速度面で有利です。 - API Key認証: 従来のApple ID / パスワード方式は、二要素認証(2FA)のため、CI環境での使用が非常に困難です。必ずApp Store Connect API Keyを発行して使用してください。
トラブルシューティングガイド
| 症状 | 原因と解決策 |
|---|---|
Missing private key for ... (iOS) |
Fastlane Matchリポジトリにアクセスできなかったか、MATCH_PASSWORDが間違っています。Secretの値を確認してください。 |
Google Api Error: Invalid request - Invalid package name (Android) |
Google Play Consoleにアプリがまだ一度も登録されていない場合に発生します。最初の配信は、必ず手動でAABをアップロードする必要があります。 |
Code signing is required for product type 'Application' (iOS) |
Xcodeプロジェクトファイル(.pbxproj)の署名設定が「Automatic」になっており、プロビジョニングプロファイルが注入されていない場合です。Matchを使用するようにプロジェクト設定を変更してください。 |
おわりに
CI/CDパイプラインの構築は、初期設定に半日程度の時間がかかる場合がありますが、一度構築しておけば、その後の数十回、数百回の配信プロセスで膨大な時間とストレスを節約できます。特にチーム単位の開発では、「誰が配信するのか」という悩みを解消し、開発文化を肯定的に変化させます。
今すぐプロジェクトにFastlaneとGitHub Actionsを導入し、開発だけに集中できる環境を整えてみてください。