はじめに
今回は 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 でエンコード) -
APPSTORE_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_BASE64
base64 -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パイプライン②~