【2025年最新版】Flutter × GitHub Actions × FastlaneでAndroidの内部テスト配布を自動化(CD)
自動化したこと
developブランチにプッシュしたタイミングでAndroidの内部テスト配布をした
注意点
今回の自動化をする上で以下の注意点があるので、もし自動化したい場合はまずはテスト配布できるようにしてからカスタマイズすることをオススメします。(動くものができてから)
- リリースノートは作成されません。
- 製品版やクローズドテストは、内部テスト配布したバージョンをGooglePlayConsoleからプロモートする必要がある
前提条件
-
flutter run
してAndroid端末でアプリを起動できる - GooglePlayConsoleでテスト配布するアプリを作成済み
- GoogleCloudPlatformでテスト配布するアプリのプロジェクトを作成済み
- Rubyのインストール(fastlaneを実行するために必要)
実装する手順
以下の9つの手順で動くようになります(全体感)
- Fastlaneのインストール
- GooglePlayConsoleとGoogleCloudPlatformの設定
- Androidプロジェクトの設定
- fastlaneの初期化
- Github Secretsの設定
- fastlane関連ファイルの設定
- 手動での初回リリース(内部テスト配布済みなら飛ばしてOK)
- Github Actionsの実装
- いざGithub Actionsを実行!
Fastlaneのインストール
HomeDirで以下を実行する
sudo gem install fastlane -NV
fastlaneをgemを使用してインストールしています。(brewでも問題ありません)
※ 開発環境によっては brew install fastlane
の方が依存関係が少なく済むケースもあります。
GoogleCloudPlatformの設定
サービスアカウントの作成
Fastlane などのツールが Google Play Developer API を使ってビルドをアップロードするには、OAuth 2.0 認証が必要です。そのためにサービスアカウントが使われます。
- IAMと管理ページに移動
- サービスアカウントに移動
- サービスアカウントを作成する
4. アカウント名などは自由に入力してください
5. ロールは「オーナー」を選択(私の場合はオーナーを選択しましたが別のロールでも問題ない) - サービスアカウントページのリストに先ほど入力したサービスアカウントが表示されていることを確認してステータスが「有効」になっていること
サービスアカウントの秘密鍵を作成
Google Play Android Developer APIを使ってビルドやメタデータを自動アップロードする際に、認証(アクセス権)を与えるためにこの鍵が必要になります。
- 「キーを追加」を押す
- 「新しい鍵を作成」を押す
- 秘密鍵の作成は「JSON」を選択する
- ローカルに保存する(保存したパスを忘れないようにしてください)
Google Play Android Developer APIを有効
fastlaneが自動でビルドしたファイルをGooglePlayConsoleにアップロードするために必要になります
「☑️ API が有効です」と表示されればOKです
GooglePlayConsoleの設定
- サービスアカウントの作成で作成したメールを指定する
- テスト自動化するアプリを選択してユーザーを招待する
Androidプロジェクトの設定
Androidのリリースには .aab ファイルのアップロードが必要です。.aab ファイルを生成するためにビルドを行いますが、そのビルドを成功させるために必要な設定です
この設定を既に実装済みの場合はこのステップを飛ばしてください
まだ実装してない方は、以下の記事より設定を行う必要があります
上記記事で設定が完了したらflutter build appbundle --release
のビルドが成功するかをチェックしてください(成功したらOK)
fastlaneの初期化
fastlaneを実行する上で必要です
cd your_flutter_project/android
fastlane init
自動テスト配布するアプリのパッケージ名を入力する
Package Name (com.krausefx.app):
サービスアカウントの秘密鍵を作成で作成した時に保存したローカルパスを入力する
入力するときには、ローカルに秘密鍵(jsonファイル)を保存した絶対パス(/Users/your-name/…)を指定する
Path to the json secret file:
- y を選ぶと、アプリの説明やスクリーンショットなどを自動で管理できます。
- 今回は n を選び、あとで fastlane supply init にて設定可能です。
Download existing metadata and setup metadata management? (y/n)
n
initが成功すると以下の2ファイルが作成されます
- android/fastlane/Appfile
- android/fastlane/Fastfile
Github Secretsの設定
関係者(または自分)以外の人にパスワードやAPIキーなどが漏洩しないようにするために使用する(セキュリティ観点)
設定方法がわからない方は以下のドキュメントを参考にしてください
以下の5つの設定が必要です
-
PLAY_CONFIG_JSON
:Google Play JSONキーファイルのBase64エンコード -
ANDROID_KEYSTORE_FILE
: KeystoreファイルのBase64エンコードしたコード -
KEYSTORE_STORE_PASSWORD
: Keystoreファイルのパスワード -
KEYSTORE_KEY_ALIAS
: Keystoreファイルののエイリアス -
KEYSTORE_KEY_PASSWORD
: Keystoreファイルのパスワード
PLAY_CONFIG_JSON
:Google Play JSONキーファイルのBase64エンコード
cd [サービスアカウントの秘密鍵を作成]で保存したdirに移動
base64 -i upload-keystore.jks
- base64コマンドを叩いて表示されたbase64コードをコピーします。
- Github Secretsで
PLAY_CONFIG_JSON
のvalueにコピーしたコードをペーストして設定する
ANDROID_KEYSTORE_FILE
:KeystoreファイルのBase64エンコード
cd [Androidプロジェクトの設定]で保存したdirに移動(おそらくandroi/app/にある)
base64 -i xxx.jks
- base64コマンドを叩いて表示されたbase64コードをコピーします。
- Github Secretsで
ANDROID_KEYSTORE_FILE
のvalueにコピーしたコードをペーストして設定する
-
KEYSTORE_STORE_PASSWORD
: Keystoreファイルのパスワード -
KEYSTORE_KEY_ALIAS
: Keystoreファイルのエイリアス -
KEYSTORE_KEY_PASSWORD
: Keystoreファイルのパスワード
これらは、.propertiesファイルに記載されている情報を元にGithub Secretsにそれぞれ設定してください
fastlane関連ファイルの設定
以下のコードをコピペしてお使いください
package_nameは変更する必要があります
json_key_file(ENV['ANDROID_JSON_KEY_PATH'])
package_name("com.example.applicationId")
AppfileはFastlaneが使うテスト配布を自動化するアプリの認証情報を定義するファイルです
default_platform(:android)
platform :android do
desc "Runs all the tests"
lane :test do
gradle(task: "test")
end
desc "Submit a new Beta Build to Crashlytics Beta"
lane :beta do
gradle(task: "clean assembleRelease")
crashlytics
end
desc "Deploy a new version to the Google Play"
lane :deploy do
gradle(task: "clean assembleRelease")
upload_to_play_store
end
desc "内部テスト用のビルドとGoogle Playへのアップロード"
lane :internal do
current_branch = `git rev-parse --abbrev-ref HEAD`.strip
if !["main", "develop"].include?(current_branch)
UI.user_error!("このレーンはmainかdevelopブランチからのみ実行できます")
end
previous_build_number = google_play_track_version_codes(track: "internal")[0]
new_version_code = previous_build_number + 1
sh("cd .. && flutter clean")
sh("cd .. && flutter pub get")
sh("cd .. && flutter build appbundle --build-number=#{new_version_code}")
upload_to_play_store(
track: 'internal',
aab: "../build/app/outputs/bundle/release/app-release.aab",
skip_upload_apk: true,
skip_upload_metadata: true,
skip_upload_images: true,
skip_upload_screenshots: true
)
end
end
このファイルで定義したコマンドを実行すると内部テスト配布をCLIから実行してくれる
Github Actionsの実装
以下のコードをコピペしてお使いください
name: Android内部テスト配信
on:
push:
branches: [ develop ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Javaのセットアップ
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '17'
- name: Flutterのセットアップ
uses: subosito/flutter-action@v2
with:
flutter-version: '3.x'
channel: 'stable'
- name: Flutterパッケージの取得
run: flutter pub get
- name: Restore .env file # 任意
run: echo "${{ secrets.ENV_FILE }}" > .env
- name: シークレット値のマスク
run: |
echo "::add-mask::${{ secrets.ANDROID_KEYSTORE_FILE }}"
echo "::add-mask::${{ secrets.KEYSTORE_STORE_PASSWORD }}"
echo "::add-mask::${{ secrets.KEYSTORE_KEY_PASSWORD }}"
echo "::add-mask::${{ secrets.KEYSTORE_KEY_ALIAS }}"
echo "::add-mask::${{ secrets.PLAY_CONFIG_JSON }}"
- name: キーストアファイルの復元
run: |
cat <<EOF | base64 --decode > android/app/upload-keystore.jks
${{ secrets.ANDROID_KEYSTORE_FILE }}
EOF
- name: key.propertiesの作成
run: |
cat <<EOF > android/key.properties
storePassword=${{ secrets.KEYSTORE_STORE_PASSWORD }}
keyPassword=${{ secrets.KEYSTORE_KEY_PASSWORD }}
keyAlias=${{ secrets.KEYSTORE_KEY_ALIAS }}
storeFile=upload-keystore.jks
EOF
- name: Play Storeの認証ファイルを設定
run: |
cat <<EOF | base64 --decode > android/play-store-credentials.json
${{ secrets.PLAY_CONFIG_JSON }}
EOF
- name: Rubyのセットアップ
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.1'
bundler-cache: true
- name: fastlaneの実行
run: |
cd android
bundle install
bundle exec fastlane internal
env:
PLAY_CONFIG_JSON: ${{ secrets.PLAY_CONFIG_JSON }}
ANDROID_JSON_KEY_PATH: play-store-credentials.json
- name: Clean up .env # 任意
run: rm .env
このyamlファイルをリモートリポジトリにプッシュすると任意のタイミングでGithub Actionsが実行されます
Restore .env file
とClean up .env
をしている箇所がありますが、これは任意になります。(削除しても良いコード)
私のFlutterプロジェクトでは.envファイルを使用しているため必要になります
※ そのためENV_FILE
をGithub Secretsに設定してない場合は設定する必要があります
.envファイルに記載されているコードをそのままvalueに貼って問題ないです。(以下のように宣言されているコードをそのままvalueに貼ってください)
EXAMPLE_API_KEY=xxx
EXAMPLE_API_KEY2=xxx
今回はdevelopブランチにプッシュしたら実行されるコードになっているため、お好きにカスタマイズしてください
いざGithub Actionsを実行!
これらの設定をリモートリポジトリに反映させます。
そのあと、developブランチに向けてプッシュするとGithub Actionsが動いて自動で内部テスト配布してくれると思います!
まとめ
私自身のアウトプットを兼ねて作成した記事になります🙇
もし、手順通り進めたがうまく動かない等ありましたら教えていただけると幸いです!
Discussion