はじめに
普段仕事ではiOSアプリを開発していますが、
昨年5月頃からFlutterに興味を持ち始め、趣味の時間でFlutterアプリの勉強を始めました。
アプリの配信は毎回手間に感じていて自動化できないか?と調査をしていた内容を共有します。
今回はAndroid編です。iOS編はこちら。
目標
Githubにコードがpushされたときに、AndroidアプリをStoreにビルド配信する。
Storeにビルド配信する。
では作業を開始します。
最終的なフォルダ構成
.
├── .github
│ └── workflows
│ ├── cd_aos.yml・・・・Android用githubActionsの設定ファイル
├── android
│ └── fastlane
│ ├── Appfile・・・・Store関係の設定が書かれたファイル
│ └── Fastfile・・・・fastlaneの設定ファイル
└── 以下省略
注意!!~今回説明しないもの~
申し訳ないのですが、今回は以下の環境設定方法については省略します。
- GooglePlayStore(deveploper)の登録や設定方法
- Githubの登録や設定方法
- GithubActionsの知識
作業の流れ
- fastlaneを用意する
- Storeに配信するための設定
- Fastfileを設定する
- github actionsを準備
- あとはコミット!!
1. fastlaneを用意する
※作業ディレクトリは、/android/ で実施します。
今回は署名の管理や面倒なビルドコマンドの省略のためにfastlaneを使用しました。
(xcodebuildやgradleなどのコマンド、flutterのコマンドからでもビルドが作成できれば、それでも良いと思います)
fastlaneには多くの便利な"アクション"が定義されています。アプリのビルドであったり、配信であったり、単体テストなども、fastlaneに定義されているアクションを利用可能です。
1-1. fastlaneを準備する
fastlaneは、iOSアプリ開発 及び Androidアプリ開発をサポートするツールです。
https://docs.fastlane.tools/
fastlaneの導入は以下のコマンドより実行します。
xcode-select --install
sudo gem install fastlane -NV
fastlane init
fastlane/にファイルが作成されたでしょうか?
作成されたAppfileやFastfileに設定を書き加えていきます。
2. Storeに配信するための設定
いよいよfastlaneを使って、ビルドから配信を行うまでの設定を行います、fastlaneの細かな設定はFastfileで行います。
と、、その前に更にいくつかの設定を行います。Storeに配信するための設定です。
2-1. fastlane supplyの準備
Android側では、fastlane supplyを使ってAndroidのStore配信を行います。
その準備として、iOSと同じようにStoreアップロード用にAPIなどを用意します。
iOSと比べて、こちらは少し面倒です。。。
2-1-1. 認証用のjsonファイルを作成
Google Play Consoleを開いて、メニューから「アカウントの詳細」を開いて「ディベロッパーアカウントID」をメモしておきます
「リンクするプロジェクトを選択」を押下すると、次のような画面となります。
そこで「新しいサービスアカウントを作成」を押下します。ダイアログが開くため指示に従っていきます。
GCPを開きます。メニューから「サービスアカウント」を開きます。アカウントがない場合は次の画像のような画面が開きます。そこで「+サービスアカウントを作成」を選びます。
サービスアカウントの作成では以下のような画面になります。サービスアカウント名を入力します。その後に「@...」の部分に、手順2でメモした「ディベロッパーアカウントID」があることを確認して下さい。また、「.iam.gserviceaccount.com」があることも確認して下さい。問題なければ「作成して続行」を押下します。
次のステップではアカウントにロールを設定します。ここでは「サービスアカウントユーザー」を設定します。
次のステップは特に何もせずに完了とします。
GCPの画面では下記のような状態になります。
キーがないため、キーを作成します。3点リーダーでメニューを開き、「鍵を管理」を選びます。
次の画面にて「新しい鍵を作成」します。
JSONを選択していることを確認して、鍵を作成します。
元の画面(GooglePlayConsole)に戻ります。元表示されていたダイアログを閉じる、再リロードすると作成したサービスアカウントの情報が反映されます。
ここでアクセス権を設定します。fastlaneのドキュメント上ではAdminが推奨されていますが、リリース関係のみ許可をして「ユーザーを招待」します。
ここまででjsonファイルの作成は完了です。
2-1-2. 作成したjsonファイルの確認
まずは下記のコマンドで動きを確認します。
fastlane run validate_play_store_json_key json_key:/path/to/your/downloaded/file.json
下記の結果が得られれば成功です。
[21:08:37]: ------------------------------------------
[21:08:37]: --- Step: validate_play_store_json_key ---
[21:08:37]: ------------------------------------------
+----------+--------------------------------------+
| Summary for validate_play_store_json_key |
+----------+--------------------------------------+
| json_key | /Users/hogetaro/Desktop/pc-api-4XXXX |
| | 4YYYYYYYYYYYYYYYYYYYYYYYYYYYYY.json |
| timeout | 300 |
+----------+--------------------------------------+
[21:08:37]: Successfully established connection to Google Play Store.
2-1-3. AppFileを設定
今作成したjsonファイルなどをAppfile内に設定します。
json_key_file("path/to/your/play-store-credentials.json") package_name("my.package.name")
記載を終えたら、
fastlane supply init
これでsupplyの準備は完了です。
3. Fastfileを設定する
fastlaneでは、Fastfileに自動化タスクを「レーン」として定義することで、1コマンド(fastlane {レーン名})でタスクが実行できるようになります。
3-1. 署名済みaabファイルをfastlaneで作成
まずはローカル環境で署名済みaabファイルをfastlaneで作成してみましょう。
default_platform(:android)
platform :android do
desc "Deploy a new version to the Google Play"
lane :deploy do
gradle(
task: "clean bundle",
build_type: "Release",
print_command: false,
properties: {
"android.injected.signing.store.file" => "{ビルドマシン内のjksファイルのパス}",
"android.injected.signing.store.password" => "{KeyStoreのパスワード}",
"android.injected.signing.key.alias" => "{keyエイリアス}",
"android.injected.signing.key.password" => "{keyエイリアスのパスワード}",
}
)
end
end
上記は、laneにdeployを定義しました。
署名つきのaabファイルを作成するfastlaneのアクションを探したところ「gradle」が使えそうなので、
「gradle」というアクションを使っています。
propertiesの設定は、ビルド時の署名情報です。リリース時に設定している内容を使います。
こちらをFastflieに記述したら、動かしてみます。
fastlane deploy
これで以下のフォルダに作成されていればOKです。
/build/app/outputs/bundle/release/app-release.aab
ログは以下のような感じです。
[20:19:34]: ▸ BUILD SUCCESSFUL in 53s
[20:19:34]: ▸ 154 actionable tasks: 133 executed, 21 up-to-date
[20:19:34]: Couldn't find any new signed apk files...
+------+---------------------+-------------+
| fastlane summary |
+------+---------------------+-------------+
| Step | Action | Time (in s) |
+------+---------------------+-------------+
| 1 | default_platform | 0 |
| 2 | clean bundleRelease | 53 |
+------+---------------------+-------------+
[20:19:34]: fastlane.tools finished successfully 🎉
3-2. ローカルで作成した署名済みaabファイルをアップロードする
3-1で作成したFastfileに以下の処理を追加します。
upload_to_play_store(
aab: "../build/app/outputs/bundle/release/app-release.aab",
skip_upload_metadata: true,
skip_upload_images: true,
skip_upload_screenshots: true
)
こちらのactionも、play storeに配信するfastlaneのアクションを探して見つけました。
Fastflieに追記したら、動かしてみます。
fastlane deploy
以下のログを得られたらOKです!
[22:37:49]: Preparing aab at path '../build/app/outputs/bundle/release/app-release.aab' for upload...
[22:38:17]: Updating track 'production'...
[22:38:19]: Preparing to upload for language 'ja-JP'...
[22:38:20]: Updating changelog for '4' and language 'ja-JP'...
[22:38:20]: Uploading all changes to Google Play...
[22:38:23]: Successfully finished the upload to Google Play
+------+----------------------+-------------+
| fastlane summary |
+------+----------------------+-------------+
| Step | Action | Time (in s) |
+------+----------------------+-------------+
| 1 | default_platform | 0 |
| 2 | clean bundleRelease | 32 |
| 3 | upload_to_play_store | 39 |
+------+----------------------+-------------+
[22:38:23]: fastlane.tools finished successfully 🎉
4. github actionsを準備
ルートの直下に、以下の構成でファイルを用意します。
.github/workflows/{githubActionsの設定ファイル名}.yml
バイナリの署名の設定を「app/build.gradle」に移動します。
署名のファイルをリポジトリ管理するようにして、以下のような設定を行います。
※iOSのfastlaneのような署名管理方法があれば教えて欲しいです・・・
signingConfigs {
release {
storeFile file("../config/KeyStore.jks") //check that the file exists
storePassword "KeyStorePassword"
keyAlias "keyAlias"
keyPassword "keyPassword"
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
署名関係については、
・supplyの設定で作成したjsonファイル
・リリース用のjksファイル
・署名設定を反映したapp/build.gradleファイル
以上が準備できていればOKと思います。
さて、ようやくですが。。yamlファイルの中身は以下を設定しました。
name: CD_Android
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches: [ master ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
aos_distribution:
runs-on: macos-11
if: |
contains(github.event.head_commit.message, '[Release]') == true && contains(github.event.head_commit.message, '[AOS]') == true
name: Distribution(AOS)
steps:
- uses: actions/checkout@v2
# install fastlane
- name: Install fastlane
run: gem install fastlane
- name: Setup flutter
uses: subosito/flutter-action@v1
with:
flutter-version: '2.5.3'
- name: Set up tools
run: |
flutter pub get
- name: ExportPath
run: |
export PATH=$PATH:${FLUTTER_HOME}/bin/cache/dart-sdk/bin
export PATH=$PATH:${FLUTTER_HOME}/.pub-cache/bin
# Build & Deploy
- name: Run builds(fastlane)
run: |
cd android/
ls
fastlane deploy
env:
JSON_KEY_PATH: ${{ secrets.JSON_KEY_PATH }}
GithubSecrets上に環境変数を定義します。
- JSON_KEY_PATH:fastlane supplyの設定で作成したJSONファイルへのパス
簡単な説明や補足
flutterのリポジトリのため、コミットメッセージに[Release]と[AOS]がある場合にTestFlightへのアップロードを行うこととしました。
if: |
contains(github.event.head_commit.message, '[Release]') == true && contains(github.event.head_commit.message, '[AOS]') == true
gradlewに関する以下のエラーが発生した場合は、gradle関連のファイルをコミットします。
エラー: Couldn't find gradlew at path
gradle関連のファイルがコミットされていなければコミットします。
android/gradle/
android/gradlew
localPropertiesFileに関する以下のエラーが発生した場合も修正します。
エラー: assert localPropertiesFile.exists()
こちらを参考にして修正しました。
Flutter SDKが見つからないエラーがあったため、SDKのセットアップ処理を追加しました。
エラー: Flutter SDK not found.
- name: Set up tools
run: |
flutter pub get
- name: ExportPath
run: |
export PATH=$PATH:${FLUTTER_HOME}/bin/cache/dart-sdk/bin
export PATH=$PATH:${FLUTTER_HOME}/.pub-cache/bin
- name: Setup flutter
uses: subosito/flutter-action@v1
with:
flutter-version: '2.5.3'
5. あとはコミット。祈るだけ。
あとはコミットしてみて祈るだけです。
さいごに
お疲れ様でした。
iOS、Androidの二部構成で記事を作成しています。もしよければiOS側の記事もご覧いただけますと幸いです。Flutterの良さは1コードで2OSに配信できることです。CD環境を整備して、そのリリース速度を加速していければと思います。