Codemagic CLI ツールと GitHub Actions で Google Play へアプリをデプロイする
本記事は、佐藤将来が執筆し、Codemagic オフィシャルブログ に投稿されたものです。
以前の記事にて、Codemagic CLI ツールと GitHub Actions で App Store Connect へアプリをデプロイする方法について解説しました。Codemagic チームはこの CLI ツールを継続的に改良し、Google Play Console への Android リリース機能を拡張しました。
Codemagic CLI ツールとは
Codemagic CLI ツールは、Codemagic の CI/CD プラットフォームを内部的に動かしている無料のオープンソースツールです。このツールの利用により、アプリのビルド、コード署名、ストアへのデプロイメントなど、モバイル開発ワークフローの効率化が可能になります。
このツールはクロスプラットフォーム対応であり、iOS と Android の両方のプロジェクトで同じツールセットを使用できます。Codemagic のクラウドベースの CI/CD サービスとは異なり、こちらの CLI ツールでは開発マシン上でローカルにビルドを実行したり、GitHub Actions などの任意の CI/CD プラットフォームと統合したりと柔軟な開発が可能です。ユーザーフレンドリーな設計を意識しており、初心者から上級者まで幅広い層に利用をお勧め出来ます。
この記事では、この CLI ツールと GitHub Actions を使って Flutter アプリを Google Play Console にデプロイする方法をご紹介します。
この記事の内容を実践することで、アプリの配布プロセスが効率化されて多くの時間やリソースの節約が可能になります。
前提条件
本記事の手順に沿っていただくには、以下のものが事前に必要です。
Google Play デベロッパーアカウントの登録
Google Play ストアでのリリースには、有料のアカウント登録が必要になります。
Google Play コンソール 上へのアプリ登録
Google Play コンソール へ該当のアプリが既に作成済みである必要があります。
事前準備
まず、GitHub Actions 上のパイプライン作成に必要な事前準備を行なっておきましょう。
keystore の確認
今回利用する Flutter プロジェクトを普段利用している IDE で開いてください。
過去に作成した /android/key.properties
上に記載されている、Google Play へのアップロード鍵となる jks ファイル及び「storePassword」「keyPassword」「keyAlias」を後からすぐ取り出せるように確認しておきましょう。
例:
storePassword=XXXXXXXX
keyPassword=XXXXXXXX
keyAlias=upload
storeFile=upload-keystore.jks
まだ jks ファイルが未作成の場合、以下のコマンドで作成してください:
keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA \
-keysize 2048 -validity 10000 -alias upload
※ 詳細は 公式ドキュメント をご覧ください
作成されたファイルと共に、作成過程で聞かれたパスワードを保管しておきましょう。
build.gradle の確認
app レベルの build.gradle
もしくは build.gradle.kts
を開いてください。
以下のように、 key.properties
を参照出来るようになっている状態になっていることを確認してください:
build.gradle
// ...
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
// ...
signingConfigs {
release {
keyAlias = keystoreProperties['keyAlias']
keyPassword = keystoreProperties['keyPassword']
storeFile = keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword = keystoreProperties['storePassword']
}
}
buildTypes {
release {
signingConfig = signingConfigs.release
}
}
// ...
}
build.gradle.kts
import java.util.Properties
import java.io.FileInputStream
plugins {
...
}
val keystoreProperties = Properties()
val keystorePropertiesFile = rootProject.file("key.properties")
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}
android {
// ...
signingConfigs {
create("release") {
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["keyPassword"] as String
storeFile = keystoreProperties["storeFile"]?.let { file(it) }
storePassword = keystoreProperties["storePassword"] as String
}
}
buildTypes {
release {
signingConfig = signingConfigs.getByName("release")
}
}
...
}
※ 詳細はこちらのドキュメントをご覧ください
※ key.properties
自体は Codemagic が実行時に自動生成するため、リポジトリへのコミットは不要です(秘匿情報のためバージョン管理はしないようにしましょう)
Google Play API の接続設定
Codemagic 経由で Google Play へアプリを公開するために必要な API の接続設定を行いましょう。
-
Google Cloud コンソールより対象アプリのプロジェクトを開いてください(必要な場合はこちらより新規作成してください)。
-
Google Play Android Developer API を有効化します。
-
Credentials メニューのページ内の「CREATE CREDENTIALS」よりサービスアカウントを新規作成します。
-
1番目のステップにて、アカウント名と説明を入力します。
-
2番目のステップにて、「Service Accounts」 > 「Service Account User」 のロールを選択します。
-
3番目のステップは不要のため、「Done」より完了します。
-
作成されたサービスアカウントの「Actions」欄より編集画面を開きます。
-
「Keys」タブのページより、「Create new key」をクリックします。
-
Key type は「JSON」を選択してキーを新規作成します。
-
このサービスアカウント用のプライベートキーがダウンロードされます。GitHub Actions 上の設定時に必要になるので、安全な場所に保管しておきましょう。
-
ここまで終えたら、Google Play コンソールへ移動しましょう。
-
「ユーザーと権限」ページ内の「新しいユーザーを招待」をクリックします。
-
メールアドレスには、先ほど作成したサービスアカウントのものを入力します。
-
「アプリを追加」より、該当アプリを選択します。
-
リリースセクションの権限を付与して「適用」をクリックします。
-
「ユーザーを招待」よりサービスアカウントを招待します。
変数とシークレットの設定
このセクションでは、後ほどパイプラインで必要となる変数やシークレットの設定方法を解説します。
Codemagic CLI ツールを GitHub Actions で利用するには、リポジトリに変数とシークレットを設定する必要があります。変数はワークフロー内で参照できるテキスト値ですが、シークレットは暗号化されているため機密情報(パスワードや証明書など)を安全に管理できます。
GitHub リポジトリの Settings > Secrets and Variables から新しい値を追加出来ます:
事前準備で用意した値を入れて行きましょう。
変数の設定
変数には以下を設定します:
-
ANDROID_KEY_ALIAS
:key.properties
内のkeyAlias
の値(例:upload
)。 -
ANDROID_KEYSTORE_FILENAME
:key.properties
内のstoreFile
の値(例:upload-keystore.jks
)。 -
GOOGLE_PLAY_PACKAGE_NAME
:Google Play に登録しているアプリのパッケージ名(例:com.example.app)。
シークレットの設定
シークレットには以下を設定しましょう:
-
ANDROID_KEYSTORE
:jks のアップロード鍵。事前準備の例のようにandroid/app/upload-keystore.jks
に保存されている場合、プロジェクトルートから以下のコマンドを実行することで base64 でエンコードされた値がクリップボードにコピー出来ます:
openssl base64 < android/app/upload-keystore.jks | pbcopy
-
ANDROID_KEYSTORE_PASSWORD
:key.properties
内のstorePassword
の値。 -
ANDROID_KEY_PASSWORD
:key.properties
内のkeyPassword
の値。 -
GOOGLE_PLAY_SERVICE_ACCOUNT_CREDENTIALS
:サービスアカウント用の Json キー。事前準備「Google Play API のアクセス設定 」内の10番目のステップで保管しておいたものになります。ファイル内の値を貼り付けてください。
GitHub Actions パイプラインの構築
このセクションでは、GitHub Actions で Flutter アプリをビルドし、Codemagic CLI ツールを使って Google Play へアップロードする方法を解説します。
YAML ファイルはプロジェクトの .github/workflows/
ディレクトリに保存し、拡張子は .yaml
となります。
GitHub Actions には Python が事前にインストールされています。Codemagic CLI ツールには Python 3.8 以上が必要ですが、setup-python により明示的にバージョン指定をすることも可能です。
まずは GitHub Actions に慣れるために Hello world!
を出力するシンプルな例から始めましょう:
name: Hello World Workflow
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Echo Hello World
run: echo "Hello, World!"
このワークフローは、リポジトリへの push をトリガーとして実行され、最新の Ubuntu 環境(ubuntu-latest
)上で動作します。
今回の要件に合った挙動とするためには、ここからいくつか修正が必要になります。まず、テスト目的でワークフローを手動トリガー(workflow_dispatch
)に設定します。また、事前に設定したリポジトリ変数やシークレットを使って、Google Play との連携ができるようにパイプラインを構成する必要があります。
以下のように順を追って、 YAML を追加・修正してください。
- コードの取得
actions/checkout@v4 アクションを使って、リポジトリのコードをランナーにチェックアウトします。
- uses: actions/checkout@v4
- Flutter のセットアップ
subosito/flutter-action を使います。ここでは stable チャンネルを利用しますが、特定のバージョンや他のチャンネルも選択可能です。
- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
- Codemagic CLI ツールのインストール
Codemagic CLI tools をインストールするジョブを追加します。
- name: Install Codemagic CLI tools
run: pip install codemagic-cli-tools
-
環境変数の設定
前のセクションにて登録した、パイプライン内で利用する環境変数を設定します。vars
プレフィックスで変数、secrets
プレフィックスでシークレットを参照します。build: runs-on: ubuntu-latest env: # Google Play 認証用サービスアカウント JSON キー GOOGLE_PLAY_SERVICE_ACCOUNT_CREDENTIALS: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_CREDENTIALS }} # Android 署名用情報 ANDROID_KEYSTORE_FILENAME: ${{ vars.ANDROID_KEYSTORE_FILENAME }} ANDROID_KEY_ALIAS: ${{ vars.ANDROID_KEY_ALIAS }} ANDROID_KEYSTORE: ${{ secrets.ANDROID_KEYSTORE }} ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} # Google Play アプリの設定 GOOGLE_PLAY_PACKAGE_NAME: ${{ vars.GOOGLE_PLAY_PACKAGE_NAME }}
-
Android キーストアのセットアップ
Android アプリの署名に使用するアップロード鍵をデコードして指定の場所に格納します。
- name: Set up Android keystore
run: |
echo "$ANDROID_KEYSTORE" | base64 --decode > android/app/$ANDROID_KEYSTORE_FILENAME
- key.properties ファイルの作成
Flutter のビルドプロセスでアプリバンドルに署名するために必要な key.properties
ファイルを作成します。
- name: Create key.properties
run: |
cat > android/key.properties << EOF
storePassword=$ANDROID_KEYSTORE_PASSWORD
keyPassword=$ANDROID_KEY_PASSWORD
keyAlias=$ANDROID_KEY_ALIAS
storeFile=$ANDROID_KEYSTORE_FILENAME
EOF
このファイルには Android 署名の設定情報が含まれており、Flutter のビルドプロセスで App Bundle の署名に使用されます。
- Android App Bundle のビルド
Google Play から最新のビルド番号を取得し、それに1を追加したビルド番号でアプリバンドルをビルドします。
- name: Build Android App Bundle
run: |
FLUTTER_BUILD_NUMBER=$(($(google-play get-latest-build-number --package-name "$GOOGLE_PLAY_PACKAGE_NAME") + 1))
flutter build appbundle --release --build-number=$FLUTTER_BUILD_NUMBER
このステップでは Google Play のすべてのトラックから最新のビルド番号を取得し、それを1つインクリメントして新しいアプリバンドルをビルドします。これにより、バージョニングの一貫性を保ちながらも疑似的なビルド番号に頼ることなく確実にバージョンを管理できます。
- Google Play への公開
ビルドされたアプリバンドルを Google Play の内部テストトラックにドラフトとして公開します。
- name: Publish to Google Play
run: |
google-play bundles publish \
--bundle "build/app/outputs/bundle/release/app-release.aab" \
--track internal \
--draft
必要に応じてトラック(
internal
、alpha
、beta
、production
)や公開オプション(--draft
の有無)を変更してください。
これで、GitHub Actions と Codemagic CLI ツールを使ってアプリを Google Play へ自動的に公開するワークフローが完成します。
このワークフローを実行すると、ビルドごとにバージョンが自動的にインクリメントされて Google Play Console 上にアップロードされます。
コードサンプル
以下がコードサンプル例の全体になります:
name: Publish to Google Play
on:
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
env:
# Google Play 認証用サービスアカウント JSON キー
GOOGLE_PLAY_SERVICE_ACCOUNT_CREDENTIALS: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_CREDENTIALS }}
# Android 署名用情報
ANDROID_KEYSTORE_FILENAME: ${{ vars.ANDROID_KEYSTORE_FILENAME }}
ANDROID_KEY_ALIAS: ${{ vars.ANDROID_KEY_ALIAS }}
ANDROID_KEYSTORE: ${{ secrets.ANDROID_KEYSTORE }}
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
# Google Play アプリの設定
GOOGLE_PLAY_PACKAGE_NAME: ${{ vars.GOOGLE_PLAY_PACKAGE_NAME }}
steps:
- uses: actions/checkout@v4
- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
- name: Install Codemagic CLI tools
run: pip install codemagic-cli-tools
- name: Set up Android keystore
run: |
echo "$ANDROID_KEYSTORE" | base64 --decode > android/app/$ANDROID_KEYSTORE_FILENAME
- name: Create key.properties
run: |
cat > android/key.properties << EOF
storePassword=$ANDROID_KEYSTORE_PASSWORD
keyPassword=$ANDROID_KEY_PASSWORD
keyAlias=$ANDROID_KEY_ALIAS
storeFile=$ANDROID_KEYSTORE_FILENAME
EOF
- name: Build Android App Bundle
run: |
FLUTTER_BUILD_NUMBER=$(($(google-play get-latest-build-number --package-name "$GOOGLE_PLAY_PACKAGE_NAME") + 1))
flutter build appbundle --release --build-number=$FLUTTER_BUILD_NUMBER
- name: Publish to Google Play
run: |
google-play bundles publish \
--bundle "build/app/outputs/bundle/release/app-release.aab" \
--track internal \
--draft
おわりに
Codemagic CI/CD はモバイル開発やコード署名、シンプルな YAML 設定に最適化された最新の環境を提供していますが、CLI ツールを活用することで Codemagic 内外のパイプラインでも追加機能を利用できます。ローカル環境でも CI/CD パイプライン上でも、これらのツールを使うことで柔軟かつ効率的にモバイルアプリのビルド・公開が可能です。
本記事では、Codemagic CLI ツールを使って GitHub Actions パイプラインから Android ビルドを Google Play へ公開する手順を紹介し、その手軽さと柔軟性を解説しました。ぜひ一度お試しください!
また、今回の Google Play へのデプロイと併せて、App Store Connect に対しても同様の処理を設定するとより一層開発フローがスムーズになります。
以下に記事があるので、ぜひご覧ください👇
Codemagic CLI ツールと GitHub Actions で App Store Connect へアプリをデプロイする
これからも Codemagic を使って快適に開発を楽しんでいきましょう!
Discussion