Open13

【Flutter】FastlaneとGithub Actionsで実現する継続デリバリー(CD)

heyhey1028heyhey1028

iOS

Key Players

Provisioning profiles:
Signing Certificates:
Bundle Identifiers:Appleがアプリを特定するのに使うアプリID
fastlane 参考

  • match:
  • gym:
  • cert
  • sign

Key Concepts

Code signing

heyhey1028heyhey1028

リリースに必要なCode Signingの背景知識

  • iOSアプリでは「誰がそのアプリを作ったのか?」と「署名後、第三者に改変されていないか?」を保証する為にアプリに制作者の署名が必要となる
  • この署名をCode Signingと呼び、この際に用いられるのがProvisioning ProfileCertificateである
  • どちらもApple Developerアカウントを持つ事で生成する事が出来る

Certificate

  • Certificateは開発用Apple Developmentと配布用(リリース用)Apple Distributionがある
  • プッシュ通知を使いたい場合はCertificate作成時点で明確に指定する必要がある
  • 手動ではMacにデフォルトで入っているキーチェーンアクセスアプリから証明書を要求するCertificateSigningRequest.certSigningRequestというcsrファイルを作成し、それを使ってcer形式の証明書ファイルが生成される
  • この証明書をダウンロードし、自身のMacのキーチェーンアクセスに登録する
  • コード署名にはこの証明書からSigining Identityと呼ばれる.p12ファイルが必要となる
  • .p12ファイルは秘密鍵と証明書のペアになっている
  • 先のcsrファイル作成時に秘密鍵と公開鍵のペアが生成されており、その秘密鍵を.p12ファイルにアタッチしてるような形
  • キーチェーンアクセスに登録された証明書から .p12ファイル を書き出せる
  • 書き出す際に任意のパスワードを要求されるので入力したパスワードは忘れずに控えておく

作成手順 参考

Bundle Identifierと「Identifiers」で登録するApp ID

  • プロジェクト作成時に定義するBundle IdentifierはAppleがアプリを特定するのに使うアプリの識別子(ID)
  • アプリをリリースするにはこのBundle IdentifierをAppleに登録する必要があり、Apple Developerアカウントの「Identifiers」で行う事が出来る
  • 「Identifiers」のタブから「App IDs」として登録する事で自分の作成しているアプリのIDを正式に登録する事になる
  • 作成時にPush通知などアプリが使う機能(Entitlements)の登録も行う

Provisioning Profile

  • アプリに関する様々な設定を含むファイルで 1) Certificate , 2) APP ID3)このアプリをインストール可能なDevice ID で構成される
  • 使用する環境によってProvisioning Profileの設定も異なり、開発用Development, 限定公開用Ad Hoc, (エンタープライズ用Enterprise)と配布(リリース)用 Distributionを作成し、使う事になる
  • 開発中アプリの配布ではUDIDが登録されたデバイスでしかアプリをインストールする事が出来ない
  • 配布用アプリではどんなデバイスでもインストール出来る必要があるので配布用プロビジョニングプロファイルではデバイス情報は含まれていない

Code Sigining

  • 署名行為はXcodeや後述のfastlaneなどでアプリをビルド(アーカイブ)する際に行われ、手動で行う事はない

参考

https://qiita.com/maiyama18/items/88567365dde2a3b3cc92#コード署名の流れ

https://zenn.dev/pressedkonbu/articles/254ca2fc3cd1ab
https://zenn.dev/miyataka/articles/64083d85c5bbca

https://www.youtube.com/watch?v=Ys2p5bFhgjI&t=426s

https://www.youtube.com/watch?v=0lJvQ-442OY

heyhey1028heyhey1028

fastlane

公式:https://docs.fastlane.tools/

必要な情報

Appfileに設定しておくと良い

  • Bundle id
  • Team name
  • Apple user name
  • App name

以上の情報がコマンド実行時に必要になる事が多いが、Appfileに定義しておく事で、「CLIからの実行」、「カスタムレーンからの実行」どちらでも省略する事が出来る

fastlaneに用意されているコマンド

  1. produce:AppStoreConnectとApple Developer Portalの両方にアプリを作成してくれる
  • CLIから実行もしくはfastlaneファイルに定義したカスタムレーン(カスタムコマンド)から実行する事が出来る
  1. cert
  2. sign
  3. match:チームで証明書、プロビジョニングプロファイルを管理する際に使う
  • プライベートレポジトリで証明書、プロビジョニングプロファイルを管理する
  • certsignが個人で証明書、プロビジョニングファイルを管理する為に使われるのに対して、複数に証明書、プロビジョニングファイルを管理するのに有効
  • match appstoreなど叩く事で、プライベートレポジトリから証明書と秘密鍵がローカルのKeychainにインストールされ、プロビジョニングファイルは~/Library/MobileDevice/Provisioning Profiles.にインストールされる
  1. gym
  2. deliver
  3. pilot

produce

Fastfile
    produce(
      username: "username",
      app_identifier: "com.example.app",
      app_name: "MyApp",
      language: "English",
      app_version: "1.0",
      sku: "com.example.app",
      team_name: "team_name"
    )

sku

skuに何を入れるべきか?

match

gym

deliver

pilot

参考

https://www.youtube.com/watch?v=A9kUT8UN2c8

https://www.youtube.com/watch?v=N_NwcDO_S_s&list=PLHchrqMOsMH4GjzlB3oVJmE6gTtXyZ-zQ

https://www.youtube.com/watch?v=zuoQS-ZFXW0&t=2900s

heyhey1028heyhey1028

Github Actionsからfastlaneを実行する

今回はtest flightと合わせて、firebase app distributionへのデリバリーも行うworkflowを作成する

事前準備

  1. App Store Connectにアプリを作成 (fastlane produceが簡単)
  2. App Store Connect API Keyの発行
  3. matchの初期設定をする (match用のgitレポジトリを作成、matchの初期設定を行う)
  4. match用のGitレポジトリのPersonal Access Tokenの発行

使用するfastlane actions

  1. create_keychain:証明書やプロビジョニングプロファイルを管理するgitレポジトリにアクセスする為のkeychainの作成 公式
  2. match:keychainにストアしたアカウント名とパスワードで証明書やプロビジョニンプロファイルをダウンロード 公式
  3. gym:アプリをリリース用、もしくはテスト配布用にビルド。以前はbuild_appと呼ばれていたがエイリアスとしてgymになった。 公式
  4. firebase_app_distribution:fastlane用のapp_distributionプラグインを以下コマンドでインストールする事で使える 公式
$ fastlane add_plugin firebase_app_distribution
  1. app_store_connect_api_key:他のactionでapi keyを使える様に変数に格納する(ex. upload_to_app_storeで必要) 公式
  2. deliver:testflightの配布ではなく、単純にアーカイブしたipaファイルをappStoreにアップロードする。以前はupload_to_app_storeと呼ばれていたがエイリアスとしてdeliverになった 公式
  3. pilot:testflightの配布。以前はupload_to_testflightと呼ばれていたがエイリアスとしてpilotになった。 公式

用意するカスタムレーン

開発版をApp Distribution配信する

※ dev,stg,prodとflavorを分けている事を想定devのアプリはapp store connectに存在しない為、app distributionを使用
流れ:

  1. create_keychain
  2. match
  3. gym
  4. firebase_app_distribution

リリース版をTestFlight配信する

※ TestFlightで最終的な動作テストを行い、問題が無い事を確認してから審査へ提出したいので、fastlaneでは審査提出までは含めていない
流れ:

  1. create_keychain
  2. match
  3. gym
  4. app_store_connect_api_key
  5. pilot

Workflowの流れ

iOSのデプロイのみ。actionsはmacos-latestで実行する。

  1. Xcodeのバージョンを指定してインストール
  2. firebase toolsのインストール:app distributionへの配信で必要となる
  3. bundlerのインストール:fastlane実行に必要となる
  4. bundle install:ローカルのGemfileにfastlaneをgem "fastlane"を記述しておく事でfastlaneをインストール
  5. flutter build ios:アーカイブ前のiosファイルをビルドする。(後にfastlane内のgymでアーカイブされる)
  6. 用意したカスタムレーンの実行
  7. (optional) git tagを打つ
  8. (optional) 自動でrelease noteを作成する

必要な環境変数

こちらに記述有り

  1. keychainインストール用に使うユーザー名
  2. keychainインストール用に使うパスワード
  3. FASTLANE_USER :fastlaneのユーザー名
  4. FASTLANE_PASSWORD :fastlaneのパスワード
  5. MATCH_PASSWORD :match初回実行時に設定を求められたパスフレーズ
  6. FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD:CIからappStoreやtestFlightへアップロードする際に必要となるパスワード
  7. FASTLANE_SESSION fastlane spaceauthを使って事前に発行。2段階認証などを通す為に必要。 公式 ➡︎ App Store Connect APIを使う場合は不要
  8. APP_STORE_CONNECT_API_KEY_ID
  9. APP_STORE_CONNECT_API_KEY_ISSUER_ID
  10. APP_STORE_CONNECT_API_KEY_CONTENT

FASTLANE_SESSIONを使うか、App Store Connect APIを使うかの2つの方法があり、どちらか一方で良いみたい (https://qiita.com/watanave/items/6e1982dfb9631172895d#2ファクタ認証の回避方法)

heyhey1028heyhey1028

アプリの登録(fastlane produce)と証明書、プロビジョニングプロファイルの管理(fastlane match)

Fastlaneの初期化

※以下全てiosディレクトリで行う
手順

  1. ios/Gemfileにfastlaneを追加
  2. bundle install
  3. fastlane initfastlane/Appfile, fastlane/Fastfileが生成される
  4. fastlane match initfastlane/Matchfileが生成される

アプリの登録

heyhey1028heyhey1028

リリース版をTestFlight配信する

fastlaneで行う事

  1. create_keychain
  2. match
  3. gym flutter build ipaコマンドを実行する為、gymは使わない
  4. app_store_connect_api_key
  5. pilot

Workflowの流れ

必要な環境変数とその取得方法

※ 変数名は任意で変えて問題ない
FASTLANE_PASSWORD

下記変数はApp Store Connect > Users and Access(ユーザーとアクセス) > App Store Connect APIで取得する事が出来る

  • APP_STORE_CONNECT_API_KEY_ISSUER_ID:上記画面のissuer ID
  • APP_STORE_CONNECT_API_KEY_ID:上記画面のキーID
  • APP_STORE_CONNECT_API_KEY_CONTENT:上記手順に従ってAPI Keyを生成した際に取得出来るp8ファイルの中身。作成時に一度だけ取得可能。-----BEGIN PRIVATE KEY-----で始まり、-----END PRIVATE KEY-----で終わる。そこまで含める。

参考

https://zenn.dev/moga/articles/752b5f5a8fc001060d1a