32
23

More than 1 year has passed since last update.

Github Actionsにて自動的にビルドする環境作成(Android編)

Last updated at Posted at 2020-05-21

概要

Github ActionsでのCI/CDの検証を行いました。
その中で他の開発プロジェクトにも定常的に適用できるようなテンプレートを作成しました。
作成したテンプレートのプロジェクトは以下になります。
github-actions-examples

今回このような環境の構築にあたっての備忘録としてここに記述しておきます。
また上記のプロジェクトは他の様々な環境において試したものであり、今回はGithub Actionsにおける Androidアプリ での自動ビルドの手法についてを中心に紹介します。

Webサイトでの自動デプロイおよびGithub Actionsでの基本的な設定についてなどはこちらの記事を参照してください。
Github Actionsにて自動的にデプロイする環境作成(Webサイト編)

またUnityでの自動ビルドの方法についてはこちらを参照してください。
Github Actionsにて自動的にビルドする環境作成(Unity編)

この他に iOS での自動ビルドの環境構築については現在検証しています。こちらも手法が確立でき次第、紹介したいと思います。

やりたいこと

  • Androidアプリを開発し、Githubにgit pushしたら自動的にビルドが行われ、成果物である apkファイル または aabファイル をダウンロードできること
  • Google Playストアにも公開可能なRelease用の署名鍵をGithub Actions上にて管理しその署名鍵を用いてビルドが行われ、成果物である apkファイル または aabファイル をダウンロードできること → 以後 Release Buildと呼称
  • Google Play Storeにリリースするための鍵を使ってビルドが行われること ← 後日更新

Build

結論

以下の内容をそれぞれ参照してください

各種解説

JDKのセットアップ

AndroidアプリのビルドはJava製のアプリケーションとしてビルドします。今回はビルドするために JDK を使用してビルドを行います(Kotlinで開発も同様)
Github Actionsでは action/setup-java を使用することで JDK のsetupができます。また、今回はJava version 1.8 でビルドするので使用するバージョンを指定します。ymlファイルには以下のように記述します。

jobs:
  build:
    steps:
      ...
      - name: setup JDK 1.8
        uses: actions/setup-java@v2
        with:
          distribution: 'zulu'
          java-version: '11'

action/setup-javav2 以降では distribution (JDKの配布先のサーバー) を指定する必要があるようになりました。対応している distribution についてはこちら を参照

Android SDKのセットアップ

JDKのセットアップができたら次は Android SDK をダウンロードしてセットアップします。
Android SDK は一般的にはAndroid Studioにてダウンロードしますが、Github Actions でBuildするためにはCLIで実行してBuildする必要があるため、Android Studio を使用しない方法でダウンロードします。
ダウンロード先のURLは Android Studioのダウンロード先 にある Command line tools only の項目から対応したOSのものをダウンロードして使用します。Github Actions 上でのBuildは Linux OS でBuildを行うため PlatformLinux のもののURLを参照して、記載します。
commandlinetools.png

wget --quiet --output-document=android-sdk.zip https://dl.google.com/android/repository/commandlinetools-linux-8092744_latest.zip
unzip -d android-sdk-linux android-sdk.zip

なお、上記の 8092744 は Command line tools のバージョンの値になります。最新のものが配信されればこの値が更新されます。

Android SDK のダウンロード、および解凍が完了したら、 build-toolsplatform-tools などを使用するための設定や環境変数であるPATHを通します。

echo y | android-sdk-linux/cmdline-tools/bin/sdkmanager --sdk_root=. "platforms;android-${{ matrix.compile-sdk }}" >/dev/null
echo y | android-sdk-linux/cmdline-tools/bin/sdkmanager --sdk_root=. "platform-tools" >/dev/null
echo y | android-sdk-linux/cmdline-tools/bin/sdkmanager --sdk_root=. "build-tools;${{ matrix.build-tools }}" >/dev/null
export ANDROID_SDK_ROOT=$PWD
export PATH=$PATH:$PWD/platform-tools/

上記で指定している値のうち

  • ${{ matrix.compile-sdk }} にはAndroidの targetSdkVersion(科開発を想定しているAndroid OSのバージョン番号。基本的には現在リリースされている最新のバージョンの番号に合わせる) の値を指定します。
  • ${{ matrix.build-tools }} にはAndroidアプリをBuildするためのbuild toolのバージョンの番号を指定します。

次に Android SDK を使用するためにlincenseを承諾します。

set +o pipefail
yes | android-sdk-linux/cmdline-tools/bin/sdkmanager --sdk_root=. --licenses
set -o pipefail

これで Android SDK の設定が完了してAndroidアプリをBuildすることができるようになります。

gradleのセットアップ

Androidでアプリをビルドするには Gradleを用います。Gradle の設定は gradlew を実行することで自動的にセットアップしてくれます。(各種Gradleコマンドもgradlew を使用して実行されます)、gradlew ファイルを実行できるようにファイルの権限を更新します。

chmod +x ./gradlew

(おまけ) Warning解消

上記までがビルドを行う設定なのですが、このままビルドを行うと Warning が出てしまうので Warning がでないようにするために途中で以下のファイルを作成します。

sudo touch /root/.android/repositories.cfg

Debug Build

Androidアプリをビルドする環境が整ったら、まずは Debug Build を行います。
Debug Buildは以下のコマンドを実行することでビルドすることができます。

./gradlew assembleDebug

Androidアプリをビルドするためには署名が必要なのですが、署名鍵を特に指定しないDebug Buildでは Android SDK がインストールされた時点で ~/.android/debug.keystore に生成されている debug用keystore の署名鍵を使用してビルドが行われます。

【参考】
debug用keystoreについて調べてみた

Release Build

Debug Buildの場合はAndroidのdebug用keystore を用いてビルドが行われましたが、Google Play StoreなどにAndroidアプリを配布する場合、debug用keystore でビルドされたapkファイル, aabファイルではアップロードした段階でエラーが発生してしまい、配布することができません。
配布するためには署名鍵を自分で作成し、作成した署名鍵を用いてビルドされたapkファイル, aabファイルをStoreにアップロードすることでアプリを配布することができます(ここではこのようなビルドをRelease Buildと呼称します)
以降では Github ActionsRelease Buildを行う方法を紹介します。
また、鍵の作成についてはこちら などを参考に作成してください。

ビルドに使用する鍵を参照できるようにする

作成した署名鍵を指定してビルドをするためには署名鍵ファイルをapp/buld.gradle にて指定することでビルドする場合に適用されます。

この時、storeFile storePassword keyAlias keyPassword の情報が必要になりますので、app/buld.gradle にこれらの情報を指定します。
これらの情報は秘匿して管理したい環境変数でもあるので、Androidにて環境変数を記述するために使われるファイルである local.properties に以上の情報を記述し、その内容をapp/build.gradle 内にて読み込ことでビルドを行うときに参照するようにします。(local.properties はデフォルトで.gitignore に記載されているので更新しても変更は反映されません)

app/buld.gradle への記述は以下のようになります。

build.gradle
Properties properties = new Properties()
def localPropertiesFile = project.rootProject.file('local.properties');
if(!localPropertiesFile.exists()){
    // localPropertiesFileがなければ作成します
    localPropertiesFile.createNewFile();
}
properties.load(localPropertiesFile.newDataInputStream())

上記の例では ビルド時に local.properties がなければ、新しく作成し、あれば既存のファイルを読み込むことで設定に適用するような処理になるように記述しています。(local.properties がない場合(Debug Buildを行う場合などにおいて)、ビルドエラーになってしまうため)

読み込んだ、local.properties の値をビルドをRelease Build の際に適用するためには以下のように記述します。

build.gradle
android {
    ...
    signingConfigs {
        release {
            // 指定したfileがある場合のみ記述
            if(!properties.getProperty("RELEASE_STORE_FILE", "").empty){
                storeFile file(properties.getProperty("RELEASE_STORE_FILE", ""))
            }
            storePassword properties.getProperty("RELEASE_STORE_PASSWORD", "")
            keyAlias properties.getProperty("RELEASE_KEY_ALIAS", "")
            keyPassword properties.getProperty("RELEASE_KEY_PASSWORD", "")
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}

このとき local.properties には以下のような環境変数を設定します。

local.properties
RELEASE_STORE_FILE=署名鍵ファイルのファイルパス(絶対パス)文字列
RELEASE_STORE_PASSWORD=ストアパスワード文字列
RELEASE_KEY_ALIAS=キーエイリアス文字列
RELEASE_KEY_PASSWORD=キーパスワード文字列

※ 上記の設定を適用した場合、ローカルで Release Build を行う場合は local.properties に以上の内容を記述し、署名鍵ファイルの情報を記述してください。

鍵の管理

本来なら署名鍵ファイルはバイナリファイルなのでどこかに保存して取得するかプロジェクトの中に埋め込んで管理します。
しかしそれだと多くの人に署名鍵の情報が知れ渡ることとなり、情報漏洩や鍵の紛失、管理の観点からリスクが大きいものとなってしまいます。

そこで今回、署名鍵の管理をGithub Secretsに保存し、秘密の環境変数として適用します

署名鍵のファイルサイズは軽微なものであるので、base64 でバイナリファイルを文字列化します。
この文字列を Github Secrets に保存し、Github Actions を実行した時にバイナリファイルに戻して保存することで秘匿されたまま鍵の管理が可能となります。まず署名鍵ファイルをbase64で文字列に出力します。

base64 Androidのビルド署名鍵.keystore

このコマンドを実行して出力された文字列を、Github Secrets に登録します。

Github Actions 内ではここで設定した Github Secrets の情報が適用されるので、以下のようにbase64 -d >でバイナリファイルに書き出します。

echo ${ANDROID_REALSE_BASE64_KEY} | base64 -d > ./release-application-key

※ ここでは ANDROID_REALSE_BASE64_KEY にバイナリファイルを base64 にて文字列にした物を Github Secrets に設定しています。
release-application-key は一時的に保存する署名鍵のファイル名となります。

local.properties に上記の各種Release Buildを行うために必要な情報を記述する

Github Actions を行う場合、Release Buildを行うために必要な情報を local.properties に以下の情報を記述します。

local.properties
RELEASE_STORE_FILE=署名鍵ファイルのファイルパス(絶対パス)文字列
RELEASE_STORE_PASSWORD=ストアパスワード文字列
RELEASE_KEY_ALIAS=キーエイリアス文字列
RELEASE_KEY_PASSWORD=キーパスワード文字列

これらの情報は全てGithub Secretsに設定し、設定した内容を以下のように local.properties に追記していくようにします。

echo ${ANDROID_REALSE_BASE64_KEY} | base64 -d > ./release-application-key
echo "RELEASE_STORE_FILE=`pwd`/release-application-key" >> ./local.properties
echo "RELEASE_STORE_PASSWORD=${ANDROID_REALSE_KEY_PASSWORD}" >> ./local.properties
echo "RELEASE_KEY_ALIAS=key0" >> ./local.properties
echo "RELEASE_KEY_PASSWORD=${ANDROID_REALSE_KEY_PASSWORD}" >> ./local.properties

これにより Github Actions にて実行される際に local.properties に値が適用された状態でビルドが行われます。

GradleでRelease Buildを行う

以下のコマンドを実行することで apkファイル を出力するRelease Buildを行います

./gradlew assembleRelease

続けて、以下のコマンドを実行することで aabファイル を出力するRelease Buildを行います

./gradlew bundleRelease

ビルドした成果物をダウンロードできるようにする

Debug Build, Release Build共にビルドを実行完了した後のapkファイル, aabファイルなどの各種成果物をダウンロードできるようにには以下の項目を追加します

- uses: actions/upload-artifact@v3
  with:
    name: outputs
    path: app/build/outputs/

これにより以下のように成果物をダウンロードすることができます。

release-build-artifact.png

apkファイルの成果物は outputs/apk/release/app-release.apk, aabファイルの成果物は outputs/bundle/release/app-release.aab にあります。

Github Actionsのファイル保存容量の制限について

上記のように Github Actions を用いて apkファイル, aabファイルのBuildを繰り返していくと、途中でエラーが発生するようになります。
これは無料プランでGitHubを利用している場合は,500MB/月までの容量までしか保存できないためです。
Githubのプランを変更するかFirebase App Distributionなどのアプリ配信サービスと連携することでエラーが発生しないようにする必要があります。(やり方などの解説は後日配信予定)

参考

Android NDK(C, C++) を用いたBuildの設定方法

ここまでのBuild設定の話は全て Android NDK(C, C++) を使用しない場合の話になります。Android NDK(C, C++)を使用する場合に追加で設定する必要があります。

Android NDKをダウンロードする

上記にてダウンロードした Android SDK の中にある sdkmanager を使用してAndroid NDK とBuildに使う CMake(CMake を使ったBuildを行う場合)を以下のようにダウンロードします。

android-sdk-linux/cmdline-tools/bin/sdkmanager --sdk_root=. --install "ndk;${{ matrix.ndk-version }}" "cmake;${{ matrix.cmake-version }}"

またこの時に指定する Android NDKCMake のバージョンについて以下のように Android Studio にて使用しているバージョンの情報を参考にして指定します

AndroidSDKInstallList.png

ダウンロードしたAndroid NDKにパスを通して使用できるようにする

使用する Android NDK の場所を指定するには local.propertiesndk.dir= にパスを指定することでBuildする時に参照してくれるので、以下のようにその値を挿入します。

echo "ndk.dir=$PWD/ndk/${{ matrix.ndk-version }}" >> ./local.properties

この Android NDK のパスの指定は普段は Android Studio 内で自動的に設定してくれています。今回はこの情報を手動で設定しています。

参考

まとめ

以上が Github Actions でAndroidのネイティブアプリを自動的にビルドするための方法を紹介になります。
いち早くプロジェクトに導入したい場合は以下の内容をそれぞれ参照(コピー)して導入してください

今後の展望

  • Google Play Storeにリリースする方法について
  • Android のテストを実行する方法について

を追加したいと思います。

32
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
23