はじめに
今回は GithubActions+Firebase App Distribution で CI/CD パイプラインの構築とテスト配布を行っていきます。サンプルプログラムはGitHub で公開中です。(シリーズで随時更新していくのでたまにエラーがあるかも)
主な参考記事:[Flutter]GitHub Actions で App Distribution にアプリをアップロードした
概要
Github にプッシュすると以下の処理を自動で行います
- 共通
- コード解析(リント)
- テスト
- OS別
- iOSのビルド&テスト配布
- Androidのビルド&テスト配布
環境変数の収集と設定
必要な環境変数のキーの一覧
- Firebase
-
FIREBASE_PROJ_DEV_NAME: プロジェクト ID -
FIREBASE_AUTH_TOKEN: Firebase のトークン -
FIREBASE_DEV_TOKEN: Firebase の Json Token -
FIREBASE_DEV_IOS_ID: Firebase のiOSアプリ ID -
FIREBASE_DEV_ANDROID_ID: Firebase のAndroidアプリ ID
-
- iOS
-
APPSTORE_CERT_BASE64: 証明書(Base64 でエンコード) -
CERT_PASSWORD: 証明書のパスワード -
MOBILEPROVISION_ADHOC_BASE64: プロビジョニングプロファイル(Adhoc) -
KEYCHAIN_PASSWORD: キーチェーンパスワード(任意の文字列で可)
-
- Android
-
ANDROID_KEY_JKS: キーストア(Base64でエンコード) -
ANDROID_STORE_PASSWORD: キーストアファイルのパスワード -
ANDROID_ALIAS_PASSWORD: キーストアファイルの ALIAS のパスワード -
ANDROID_KEY_ALIAS: キーストアファイルの ALIAS 名
-
設定方法
- 後述の手順に従って環境変数を収集する
- GitHubの
SettingsタブのサイドバーからSecurity/Secrets and variables/Actionsを選択 -
New Repository Secretから環境変数を登録
Firebase
- エディタ(VSCode等)の一斉置換機能で
com.example.{プロジェクト名}をcom.{任意の文字列}.{プロジェクト名}に置換- 私は屋号(開発用名義やチーム名)を
{任意の文字列}にしている - Androidならスネークケース,iOSならキャメルケースで書くことに注意
- 私は屋号(開発用名義やチーム名)を
- Firebaseにログイン
- プロジェクトを作成する
- 名前はローカルのプロジェクト名と同じで良い(単語頭文字は大文字にしても良い)
- あとはデフォルトの設定で作成
- 作成できたらプロジェクトの個別ページへ
- Flutterを追加する
- 画面の指示に従ってステップ1&2を実行
- ステップ1ですでに行なっているタスク(FlutterSDKのインストールやプロジェクトの作成)は省略可
- ステップ2は必須
dart pub global activate flutterfire_cli flutterfire configure --project=fluttersample-29ba1
-
pubspec.yamlにfirebase_coreを追加- バージョンはリファレンスを参照(2025/2/13時点で3.11.0)
pubspec.yamldependencies: flutter: sdk: flutter #追加 firebase_core: ^3.11.0 - ログイントークンを取得
firebase login:ci- 取得したトークンは
FIREBASE_AUTH_TOKENにセット
- 取得したトークンは
- ステップ3は
main.dartを編集main.dartimport 'package:flutter/material.dart'; //追加 import 'firebase_options.dart'; import 'package:firebase_core/firebase_core.dart'; void main() async { runApp(const MyApp()); //追加 await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ); } //省略 - Firebaseのコンソールに戻りプロジェクトの設定/全般に移動
- プロジェクトIDを取得
- アプリIDをiOS,Androidのそれぞれのタブで取得
- プロジェクトの設定/サービスアカウントに移動して秘密鍵を作成
- 取得したJSONファイルの中身を
FIREBASE_DEV_TOKENにセット
- 取得したJSONファイルの中身を
- AppDistributionを有効にする
- Firebase のプロダクトと機能/実行からAppDistributionを選択し
- テスターのグループを作成してテスターのメアドを追加
- グループ名は後に使用する
iOS
-
iOS のバージョンを14.0 に変更
-
キーチェーンアクセスから証明書要求ファイル作成
- Apple公式の証明書署名リクエストを作成するを参考
- 作成した
CertificateSigningRequest.certSigningRequestはわかりやすいフォルダに保存
-
Apple DeveloperのCertificates で証明書を作成する
-
distribution.cerを.p12で書き出す -
Apple Developer から AppID を作成(参考:アプリIDを登録する)
- バンドル ID には
com.example.yourappnameを入力(yourappnameは自分のアプリ名に置き換え) - Apple Developer/Profile からプロファイルを作成
- 用途に Ad Hoc を選択
- 作成した AppID を選択
- 取得したCertificatesを選択
- テスターに含めるデバイスを選択
- 名前を入力して作成
- こちらもbase64で書き出して
MOBILEPROVISION_ADHOC_BASE64base64 -i {自分のProvisioningProfile}.mobileprovision | pbcopy
- バンドル ID には
-
Xcode
BuildSettings->Code Siging IdentityでCertificates in KeychainからApple Distributionを選択

画像では2つあるが普通は1つしか無いはず(なぜか私はチームIDが2つあった) -
Xcode
Signing & Capablities-
Automatic manage signingのチェックを外す -
Provisioning Fileで作成した Profile を選択- ない場合は
import fileからディレクトリを探す
- ない場合は
-
Provisioning profile *** doesn't include signing certificateと表示されたら証明書と Profile が一致してないので要確認
-
-
ExportOption.plistの作成
- ちゃんと作成するなら【Flutter】flutter build ipa でipaファイルが生成されない を参考にExportOption.plistを作成して中身を
EXPORT_OPTIONSにセットするのだが,先ほど作成した.mobileprovisionファイルが必要となるが形式が違うためエラーとなる - 以下にExportOptions.plistの形式を示すので{}を書き換えて
EXPORT_OPTIONSにセット<!-- ExportOptions.plist --> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>compileBitcode</key> <false/> <key>destination</key> <string>export</string> <key>method</key> <string>ad-hoc</string> <key>provisioningProfiles</key> <dict> <key>{バンドルID}</key> <string>{アプリ名}</string> </dict> <key>signingCertificate</key> <string>Apple Distribution</string> <key>signingStyle</key> <string>manual</string> <key>stripSwiftSymbols</key> <true/> <key>teamID</key> <string>{チームID}</string> <key>thinning</key> <string><none></string> </dict> </plist>
- ちゃんと作成するなら【Flutter】flutter build ipa でipaファイルが生成されない を参考にExportOption.plistを作成して中身を
-
KEYCHAIN_PASSWORDは好きに決めてよし
これでiOSの下準備が完了
Android
-
./androidに移動cd android -
以下のコマンドでkeystoreを作成
keytool -genkey -v -keystore ./key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key キーストアのパスワードを入力してください: 新規パスワードを再入力してください: 識別名を入力します。サブコンポーネントを空のままにする場合はドット(.)を1つ入力し、中カッコ内のデフォルト値を使用する場合は[ENTER]を押します。 姓名は何ですか。 [Unknown]: 組織単位名は何ですか。 [Unknown]: 組織名は何ですか。 [Unknown]: 都市名または地域名は何ですか。 [Unknown]: 都道府県名または州名は何ですか。 [Unknown]: この単位に該当する2文字の国コードは何ですか。 [Unknown]: CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknownでよろしいですか。 [いいえ]: y 10,000日間有効な2,048ビットのRSAのキー・ペアと自己署名型証明書(SHA384withRSA)を生成しています ディレクトリ名: CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown [./key.jksを格納中] -
./android直下にkey.propertiesを作成./android/key.propertiesstorePassword=パスワード keyPassword=パスワード keyAlias=key storeFile=key.jks- パスワードはkeystoreを作成した時のパスワード
- 上から3つは順に
ANDROID_STORE_PASSWORD,ANDROID_ALIAS_PASSWORD,ANDROID_KEY_ALIASにセット -
key.properties自体はローカルでビルドする際に必要 - 機密情報なので
.gitignoreにandroid/key.propertiesを追加
-
key.jksをbase64に書き出してANDROID_KEY_JKSにセットbase64 -i ./android/key.jks | pbcopy
-
./android/app/build.gradleを編集build.gradleplugins { //省略 } //追加 def keystorePropertiesFile = rootProject.file("key.properties") android { //省略 //追加ここから signingConfigs { release { if (keystorePropertiesFile.exists()) { def keystoreProperties = new Properties() keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) keyAlias keystoreProperties['keyAlias'] keyPassword keystoreProperties['keyPassword'] storeFile file(keystoreProperties['storeFile']) storePassword keystoreProperties['storePassword'] } } } //追加ここまで //省略 }
次回
次は実際にGitHubActionsで実行するワークフローのコードを書きます.
Flutterの初心者ベストプラクティス ~CI/CDパイプライン②~











