やる気駆動型エンジニアの備忘録

WPF(XAML+C#)の話題を中心に.NET/Android/CI やたまに趣味に関するブログです

(Android)APK をCI ツールで生成する方法メモ

Android アプリのAPK ファイルの生成をCI ツールを使用して自動化する際のメモです。
Android Studio だとメニューからAPK を生成できますが、例えばGit のmaster ブランチへpush されたらAPK を生成する といったことができれば、デプロイも簡単になります。

今回は以下のような環境下でどうすればAPK の生成を自動化できるか?という観点で調査・実践した結果をまとめています。

開発環境

開発用PC
  • OS : Windows10 Enterprise 64bit
  • 開発環境 : Android Studio 3.1.1
  • Gradle : 3.3
サーバー(オンプレミス)

目的

業務用のAndroid アプリ開発で、APK ファイルの生成を自動化したい。

アプリの署名について

Android アプリの全てのAPK は、デジタル署名されている必要があります。
署名に関する情報は以下のページを参照してください。

アプリの署名 | Android Studio

この署名はAndroid Studio から行うことができます。
上記URL の[キーとキーストアを生成する] の手順を行えば、キーストアが作成され、以降はパスワードを入力するとAPK ファイルを作成することができます。

ただし、これはあくまで"手動"でAPK を作成する方法です。


APK を生成する方法

前述した方法を除くと、APK を署名する方法は大きく分けて2つあります。

1. Gradle に自動署名を設定する
この方法はbuild.gradle に「キー エイリアス」「キー パスワード」「ストア パスワード」「ストアファイルのパス」を設定することでアセンブリのビルドと同時に署名もやってしまおうというものです。
上記URL の[手動で APK に署名する] あたりからが参考になります。

2. 未署名のAPK にツールを使用して署名する
この方法は、未署名のAPK を作り、zipalignapksigner を使用してコマンドラインから署名するというものです。
上記URL の[署名されていない APK をビルドして手動で署名する] が参考になります。

どちらの方法も試してみましたが、1.の方が手順が少なく、簡単なので1.の方法を採用しました。
(2.の方法でも実現できなくは無いですが、割と手順が多く、ビルドに成功するまでに時間がかかります。)

Gradle に自動署名を設定する方法

Gradle に設定する方法ですが、これもいくつか手法が用意されています。
いずれの方法もbuild.gradle を使用することは変わりません。

1. build.gradle に直接署名情報を設定する
これは単純にbuild.gradle に署名情報に必要な内容を直値で書き込むというものです。
リファレンスにもありますが、イメージとしては以下のようになります。

android {
    signingConfigs {
        release {
            storeFile file("my-release-key.jks")
            storePassword "password"
            keyAlias "my-alias"
            keyPassword "password"
        }
    }
    ...
  }

署名情報('keyAlias' など)は、キーストアを生成した際の内容を入力します。

2. 署名情報を記載したファイルをbuild.gradle から参照する
この方法では、署名情報を記述したファイルを別途用意し、そのファイルをbuild.gradle ファイルから読み込むというものです。
以下のページが非常に参考になります。

techlife.cookpad.com


APK を配布する上で(配布先の環境によりますが)基本的にAPK に署名情報を直接設定するのはかなり心配です。
よって、2.の方法で実現します。

上記URL にもありますが、別ファイルとしてrelease.gradle を作成し、build.gradleファイルから署名情報を読み込みます。

[release.gradle]

signingConfigs {
    config {
        storeFile file("<.keystore ファイルのパス>")
        storePassword "<ストア パスワード>"
        keyAlias "<キー エイリアス>"
        keyPassword "<キー パスワード>"
    }
}

[build.gradle]

android {
    signingConfigs {
        def releaseSettingGradleFile = new File("${project.rootDir}/release.gradle")
        if (releaseSettingGradleFile.exists()) {
            apply from: releaseSettingGradleFile, to: android
        }
    }
...

    productFlavors {
        releaseConfig {
            // フレーバーを設定している場合は、signingConfig から署名構成情報を参照する必要がある。
            // signingConfigs.config はrelease.gradle で設定したconfig 構成を使用する という意味。
            signingConfig signingConfigs.config
        }
    }
...
}

これでビルド構成の準備ができました。
あとはコマンドラインから以下のコマンドを叩けば project_name/module_name/build/outputs/apk/ フォルダにAPK ファイルが生成されます。

./gradlew.bat :app:assembleRelease

CI ツール(Jenkins)でAPK 生成を自動化する

長くなりましたが、Jenkins を使用してAPK の生成を自動化してみます。
今回はPipeline スクリプトを使用して
1. Git のリポジトリから最新ソースを取得する
2. ビルドを実行してAPK を作成する
3. 作成されたAPK を成果物として保存する
という手順を実行します。

node(<スレーブ名>) {
    stage('Get Repository') {
        git branch: 'master', credentialsId: ..., url: 'http://...'
    }

    stage('Build Relase') {
        bat './gradlew.bat clean'
        
        // APK を生成する。
        bat './gradlew.bat :app:assembleRelease'
    }
    
    stage('Artifacts') {
        // APK ファイルを成果物として保存する。
        archiveArtifacts artifacts: 'app/build/outputs/apk/<APK ファイル名>apk', fingerprint: true, onlyIfSuccessful: true
    }
}

必要最低限のスクリプトですが、これでAPK ファイルの自動生成とアーカイブができました。


個人だったり企業向けだったり、Play ストアに配布するかどうかやセキュリティ ポリシーの制約などなどありますが、要件に合わせて適切な方法を選べるようにしたいところです。
Android のセキュリティに関する情報は公式リファレンスに勝る情報は無いので、まずはそちらを参考にしていくのがベターな選択肢だと思います。