1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Flutterの初心者ベストプラクティス ~CI/CDパイプライン①~

Last updated at Posted at 2025-02-18

はじめに

今回は GithubActions+Firebase App Distribution で CI/CD パイプラインの構築とテスト配布を行っていきます。サンプルプログラムはGitHub で公開中です。(シリーズで随時更新していくのでたまにエラーがあるかも)

主な参考記事:[Flutter]GitHub Actions で App Distribution にアプリをアップロードした

概要

Github にプッシュすると以下の処理を自動で行います

  • 共通
    • コード解析(リント)
    • テスト
  • OS別
    • iOSのビルド&テスト配布
    • Androidのビルド&テスト配布

これをまとめたのが以下の図。
whole_workflow.png

環境変数の収集と設定

必要な環境変数のキーの一覧

  • 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 名

設定方法

  1. 後述の手順に従って環境変数を収集する
  2. GitHubのSettingsタブのサイドバーからSecurity/Secrets and variables/Actionsを選択
  3. New Repository Secretから環境変数を登録

Firebase

  1. エディタ(VSCode等)の一斉置換機能でcom.example.{プロジェクト名}com.{任意の文字列}.{プロジェクト名}に置換
    • 私は屋号(開発用名義やチーム名)を{任意の文字列}にしている
    • Androidならスネークケース,iOSならキャメルケースで書くことに注意
  2. Firebaseにログイン
  3. プロジェクトを作成する
    • 名前はローカルのプロジェクト名と同じで良い(単語頭文字は大文字にしても良い)
    • あとはデフォルトの設定で作成
    • 作成できたらプロジェクトの個別ページへ
  4. Flutterを追加する
    firebase1.png
  5. 画面の指示に従ってステップ1&2を実行
    firebase2.png
    • ステップ1ですでに行なっているタスク(FlutterSDKのインストールやプロジェクトの作成)は省略可
    • ステップ2は必須
      dart pub global activate flutterfire_cli
      flutterfire configure --project=fluttersample-29ba1
      
  6. pubspec.yamlfirebase_coreを追加
    pubspec.yaml
    dependencies:
        flutter:
            sdk: flutter
        #追加
        firebase_core: ^3.11.0
    
  7. ログイントークンを取得
    firebase login:ci
    
    • 取得したトークンはFIREBASE_AUTH_TOKENにセット
  8. ステップ3はmain.dartを編集
    main.dart
    import '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,
      );
    }
    //省略
    
  9. Firebaseのコンソールに戻りプロジェクトの設定/全般に移動
  10. プロジェクトIDを取得
    • FIREBASE_PROJ_DEV_NAMEにセット
      Firebase3.png
  11. アプリIDをiOS,Androidのそれぞれのタブで取得
    • FIREBASE_DEV_IOS_ID/FIREBASE_DEV_ANDROID_IDにセット
      Firebase5.png
  12. プロジェクトの設定/サービスアカウントに移動して秘密鍵を作成
    Firebase6.png
    • 取得したJSONファイルの中身をFIREBASE_DEV_TOKENにセット
  • AppDistributionを有効にする
    • Firebase のプロダクトと機能/実行からAppDistributionを選択し
  • テスターのグループを作成してテスターのメアドを追加
    FAD_tester.png
    • グループ名は後に使用する

iOS

  1. iOS のバージョンを14.0 に変更

    • Xcodeでios/Runnner.xcworkspaceを開きRunnerを選択
    • General/Minimum Developmentsからバージョンを変更
      ios_version.png
  2. キーチェーンアクセスから証明書要求ファイル作成

  3. Apple DeveloperのCertificates で証明書を作成する

    • 新規作成
      ios_cert1.png

    • Apple Distributionn を選択
      ios_cert2.png

    • 取得した証明書要求ファイル(CertificateSigningRequest.certSigningRequest)をセット
      ios_cert3.png

    • ダウンロードする

      • distribution.cerファイルがダウンロードされるのでわかりやすいフォルダへ移動
        ios_cert4.png
  4. distribution.cer.p12で書き出す

    • ログイン->自分の証明書を選択し.cerファイルをドラッグ&ドロップ
      スクリーンショット 2025-01-29 14.20.08.png
    • 右クリックで"~を書き出す"を選択
    • 書き出し先と名前を選択
    • パスワードを入力しAPPSTORE_CERT_BASE64にセット
    • Base64へエンコードしてAPPSTORE_CERT_BASE64にセット
      • エンコードするコマンドはbase64 -i {証明書名}.p12 | pbcopy
      • クリップボードにコピーされているのでそのままペースト
  5. Apple Developer から AppID を作成(参考:アプリIDを登録する)

    • バンドル ID にはcom.example.yourappnameを入力(yourappnameは自分のアプリ名に置き換え)
    • Apple Developer/Profile からプロファイルを作成
    • 用途に Ad Hoc を選択
      ios_pro1.png
    • 作成した AppID を選択
      ios_pro2.png
    • 取得したCertificatesを選択
      • 必ずDistributionを選ぶ
      • 同日にCertificatesを複数作成するとここで判別不能になるので注意
        ios_pro3.png
    • テスターに含めるデバイスを選択
      ios_pro4.png
    • 名前を入力して作成
    • こちらもbase64で書き出してMOBILEPROVISION_ADHOC_BASE64
      • base64 -i {自分のProvisioningProfile}.mobileprovision | pbcopy
  6. Xcode BuildSettings->Code Siging IdentityCertificates in KeychainからApple Distributionを選択
    ios_codesign.png
    画像では2つあるが普通は1つしか無いはず(なぜか私はチームIDが2つあった)

  7. Xcode Signing & Capablities

    • Automatic manage signingのチェックを外す
    • Provisioning Fileで作成した Profile を選択
      • ない場合はimport fileからディレクトリを探す

    ios_sign&cap.png

    • Provisioning profile *** doesn't include signing certificateと表示されたら証明書と Profile が一致してないので要確認
  8. 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>&lt;none&gt;</string>
      </dict>
      </plist>
      
      • チームIDはAppleDeveloperの右上の英数字
        teamid.png
      • 正式な作成方法は別記事で後日書きます
  9. KEYCHAIN_PASSWORDは好きに決めてよし

これでiOSの下準備が完了

Android

  1. ./androidに移動

    cd android
    
  2. 以下のコマンドで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を格納中]
    
  3. ./android直下にkey.propertiesを作成

    ./android/key.properties
    storePassword=パスワード
    keyPassword=パスワード
    keyAlias=key
    storeFile=key.jks
    
    • パスワードはkeystoreを作成した時のパスワード
    • 上から3つは順にANDROID_STORE_PASSWORD,ANDROID_ALIAS_PASSWORD,ANDROID_KEY_ALIASにセット
    • key.properties自体はローカルでビルドする際に必要
    • 機密情報なので.gitignoreandroid/key.propertiesを追加
  4. key.jks をbase64に書き出してANDROID_KEY_JKSにセット

    • base64 -i ./android/key.jks | pbcopy
  5. ./android/app/build.gradleを編集

    build.gradle
    plugins {
        //省略
    }
    //追加
    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パイプライン②~

参考文献

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?