AndroidStudioプロジェクトでgradlewにプロパティ渡すことで署名ビルドを行う

More than 1 year has passed since last update.

gradlewでビルド

JenkinsでAndroidアプリのCIとかさせる場合、Gradle Wrapperの仕組みによりAndroidStudioプロジェクト配下にデフォルトで作成される gradlew スクリプトが結構便利で助かる。
シェルで実行のジョブを作成し、そのまま

$ ./gradlew clean build

とかやると簡単にapkを生成してくれるスグレモノ。

あんまGradle自体には詳しくないのでそのうちガツッと読んどこう。
http://gradle.monochromeroad.com/docs/userguide/gradle_wrapper.html

署名をアドホックに行いたい

普通は build.gradle 内に signingConfigs で署名情報を設定しておくと思うのだけれど、今回はそれを完全に分離して gradlew でのビルド時に引き渡したい。

軽く gradlew のソース読むとこいつ自身のコマンドライン引数の本格的な利用箇所は最終行の

gradlew
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

のみ。
すべてをまるっとそのまま食わせているようなので少し調べることに。

まず、ドキュメントのオプションに関する項を読み進めてみると、
http://gradle.monochromeroad.com/docs/userguide/tutorial_this_and_that.html#sec:gradle_properties_and_system_properties

projectオブジェクトに追加するプロパティは、コマンドラインオプションの-Pオプションで設定することもできます

こんな記述が。
なるほど -P 使えばいわゆる properties として引き渡せるのか。
がしかし、肝心の署名にまつわるプロパティ名って何になるんだ・・・?

ソースみてみた

結局 AndroidのGradleプラグイン公式 に乗ってた手順にしたがってソース落として見てみることに。
Gradleプラグインのお作法とかまったくもって知らないけど、とりあえずレベルでドキュメント読んでみると Plugin インターフェイスの apply メソッドを実装して作成していく形らしいのでそれっぽいクラス探してgrepしてたらみっけた。

BasePlugin.groovy
    private SigningConfig getSigningOverride() {
        if (project.hasProperty(PROPERTY_SIGNING_STORE_FILE) &&
                project.hasProperty(PROPERTY_SIGNING_STORE_PASSWORD) &&
                project.hasProperty(PROPERTY_SIGNING_KEY_ALIAS) &&
                project.hasProperty(PROPERTY_SIGNING_KEY_PASSWORD)) {

こいつら4つが定義されてれば署名情報をオーバーライドするっぽい。
さらにこの定数値たちを辿って行くと

AndroidProject.java
    String PROPERTY_SIGNING_STORE_FILE = "android.injected.signing.store.file";
    String PROPERTY_SIGNING_STORE_PASSWORD = "android.injected.signing.store.password";
    String PROPERTY_SIGNING_KEY_ALIAS = "android.injected.signing.key.alias";
    String PROPERTY_SIGNING_KEY_PASSWORD = "android.injected.signing.key.password";

いたわぁ。

結果

最終的にはこんな感じ。

$ ./gradlew signingReport -Pandroid.injected.signing.store.file=[キーストアファイルへのパス] -Pandroid.injected.signing.store.password=[キーストアのパスワード] -Pandroid.injected.signing.key.alias=[キーのエイリアス] -Pandroid.injected.signing.key.password=[キーのパスワード]

Variant: release に署名情報が反映されてるか一応確認後

$ ./gradlew clean assembleRelease -Pandroid.injected.signing.store.file=[キーストアファイルへのパス] -Pandroid.injected.signing.store.password=[キーストアのパスワード] -Pandroid.injected.signing.key.alias=[キーのエイリアス] -Pandroid.injected.signing.key.password=[キーのパスワード]

で署名付きリリースパッケージング。

まとめ

長々と調査しちゃったけど、最初から build.gradle に自前で用意したパラメータ用のプレースホルダ的な動作を書いておけばコレ直で指定することもない気がする。調べる労力考えると絶対そっちが楽。

あとAndroidStudioのほうのソース内にある ExportSignedPackageWizard クラス読むとわかるんだけど、結局AndroidStudioでの署名ビルドウィザードでもダイアログで指定されたキー値で↑の4つのプロパティをオーバーライドしてビルドしているだけっぽい。そういう意味では gradle.build 汚さずに済む・・・のか・・・?