GitHub Actions + gradle play publisher(GPP)でStoreに自動デプロイする設定を説明する。
fastlaneなどでPlay Storeにデプロイした経験がある人向けの説明。初心者向けではない。
大体、公式のREADMEどおりに設定すれば良いが、少しだけハマりどころもある。
構成
アプリのソースコードはGitHub上に公開する。
第三者によるアプリのビルドは許可するが、Store上の自分のアプリを上書きする形でのアップロードは禁止する。
なので、keystore1、keystoreのパスワードなどの情報は、リポジトリ管理対象のファイルには含めない。
Storeアップロードに使うGCPの認証情報もファイルに含めない。
Storeのアップロード先は内部テストトラックで、アップロード時点で完全公開とする。
アプリの形式はapkでなくaabとする。
gradle play publisherの設定
事前設定
gradle play publisherのREADMEに書かれている設定をしておく。
https://github.com/Triple-T/gradle-play-publisher#prerequisites
Storeへの初回アップロード、署名用のkeystoreの準備、デプロイに使うGCPのサービスアカウントの設定。
GCPのサービスアカウントの認証用JSONは、環境変数ANDROID_PUBLISHER_CREDENTIALSに設定する方式を採用する。
build.gradleの記述
apply plugin: 'com.android.application'
apply plugin: 'com.github.triplet.play'
play {
track = "internal"
status = "completed"
defaultToAppBundles = true
enabled = (System.getenv("ANDROID_PUBLISHER_CREDENTIALS") != null)
}
trackとstausはデフォルト値のままなので本来は記述不要だが、いちいちデフォルト値を覚えていられないので記述する。
enabledの設定が重要。
GCPの認証情報が入った環境変数が未定義のときは、GPPを無効化するという設定。
この設定をしないと、普段の開発のときのビルドでもGPPのエラーが発生してビルドできない。
PCからアプリをStoreにデプロイする
アプリのルートディレクトリから以下のコマンドを実行する。
設定が上手くいっていれば、Storeの内部テスト版にアップロードできる。
export ANDROID_PUBLISHER_CREDENTIALS=`cat <GCPのサービスアカウントの認証情報の入ったJSONファイルのパス>`
export STORE_PASSWORD=XXX
export KEY_ALIAS=XXX
export KEY_PASSWORD=XXX
./gradlew publishBundle \
-Pandroid.injected.signing.store.file="<keystoreファイルのパス>" \
-Pandroid.injected.signing.store.password=$STORE_PASSWORD \
-Pandroid.injected.signing.key.alias="$KEY_ALIAS" \
-Pandroid.injected.signing.key.password=$KEY_PASSWORD
署名に必要な情報はbuild.gradleに記述するのではなく、コマンド実行時にプロジェクトプロパティとして渡すようにする。これは、CIを実行するときの布石。
GitHub Actions + gradle play publisherでStoreにデプロイする
GitHub ActionsのSecretsの定義
GitHubのリポジトリのページ -> Settings -> Serectsから以下を設定する。
- ANDROID_PUBLISHER_CREDENTIALS
- GCPのサービスアカウントの認証情報のJSONファイル。テキストエディタで開いてコピペする。
- ENCODED_KEYSTORE
- keystoreファイルをbase64でencodeした値を設定する。
- 「base64 -i 」で値を生成する。
- STORE_PASSWORD
- keystoreのパスワード。
- KEY_ALIAS
- keystoreのalias。セキュアな情報でない気がするが、Secretsにまとめた方が分かりやすいと思っている。
- KEY_PASSWORD
- keystoreのkeyのパスワード。
GitHub Actionsのワークフローの設定
GitHub上でprereleaseをしたら、PlayStoreにアップロードするように設定する。
タグ名の先頭には「vX.Y.Z」を付けるものとする。
name: pre-release
on:
push:
tags:
- "v[0-9].[0-9]+.[0-9]+*"
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 11
- name: Cache Gradle Dependencies
uses: actions/cache@v2
env:
cache-name: cache-gradle-depen
with:
path: ~/.gradle
key: ${{ runner.os }}-${{ hashFiles('build.gradle') }}-${{ hashFiles('app/build.gradle') }}
- name: Download Dependencies
run: ./gradlew androidDependencies
- name: Test
run: ./gradlew testReleaseUnitTest
- name: Publish App Bundle
run: |
echo $ENCODED_KEYSTORE | base64 -d > "`pwd`/keystore.jks"
./gradlew publishBundle \
-Pandroid.injected.signing.store.file="`pwd`/keystore.jks" \
-Pandroid.injected.signing.store.password=$STORE_PASSWORD \
-Pandroid.injected.signing.key.alias=$KEY_ALIAS \
-Pandroid.injected.signing.key.password=$KEY_PASSWORD
env:
ENCODED_KEYSTORE: ${{ secrets.ENCODED_KEYSTORE }}
ANDROID_PUBLISHER_CREDENTIALS: ${{ secrets.ANDROID_PUBLISHER_CREDENTIALS }}
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
解説することはほぼなし。PCでデプロイしたときのコマンドをほぼそのまま実行しているだけ。
ENCODED_KEYSTOREは、「echo $ENCODED_KEYSTORE | base64 -d > "pwd
/keystore.jks"」というコマンドで、keystoreファイルに戻している。
UnitTestの実行しないなら、./gradlew testReleaseUnitTestは除去でOK。
例:実際に使っている設定ファイル
- build.gradle
- GitHub Actionsのworkflow
-
keystoreは暗号化されていると思っている。これが合っていれば、普通にリポジトリ管理対象にして良い気がしている。しかし、Androidテスト全書だとAESで暗号化している。それにならって、生のkeystoreはをリポジトリ管理対象にしなかった。面倒だが安全ではある。 ↩