BITRISEを用いたAndroidアプリの自動配布

More than 1 year has passed since last update.


BITRISEを用いたAndroidアプリの自動配布

Androidその2 Advent Calendar 2016 3日目になります!

ここでは、 Android アプリの最新版を自動でテスターに配布する仕組みを説明します :blush:


はじめに

友人とアプリ開発を始めることになり、BITRISEでAndroidアプリ開発のCI環境を構築しました。

開発中のapkを友人や家族に使ってもらう際のハードルをできるだけ下げたくて、Google Play経由でアプリを配布する方法を検討しました。

すでにBITRISEとAndroidの連携は分かりやすい記事がいくつかありますので、

今回はBITRISEを通じてGoogle Play Developer Consoleにα版apkをアップロードする点を中心に記事にしたいと思います。


概要

bitrise.jpeg



  • 背景


    • GitHubのdevelopブランチ更新時に、apkをα版としてGoogle Playに自動アップロードしたい

    • β版はGoogle Play経由でα版からプロモートしたい




  • やったこと



    • gradle-play-publisherでGoogle Playに自動アップロードするgradle taskを作成する

    • apkのバージョンをBITRISEのビルド番号に対応づける

    • BITRISEでアプリのreleaseビルドを自動化する

    • BITRISEでGoogle Playへのアップを自動化する




バージョンをインクリメントしないとGoogle Playにアップロードできないので注意



手順


1. Google Playのサービスアカウントのキーファイルを取得する


2. gradle-play-publisherでGoogle Playにアップロードするgradle taskを作成する



  • build.gradle(Project)を修正



    • gradle-play-publisherdependenciesに追加する




build.gradle(Project)

buildscript {

repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.1'
     // gradle-play-publisherのプラグインの読み込み設定を追加
classpath 'com.github.triplet.gradle:play-publisher:1.1.5'
}
}

allprojects {
repositories {
jcenter()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}




  • build.gradle(Module)を修正



    • gradle-play-publisherのプラグインの読み込み設定を追加する

    • バージョン情報をgradleの実行オプション化する

    • キーストアをgradleの実行オプション化する




build.gradle(Module)

apply plugin: 'com.android.application'

// gradle-play-publisherのプラグインの読み込み設定を追加
apply plugin: 'com.github.triplet.play'

// gradle実行オプションからバージョン情報を取得
final exampleVersionCode = hasProperty('version_code') ? property('version_code').toInteger() : 1
final exampleVersionName = hasProperty('version_name') ? '0.1.0.' + property('version_name') : '0.1.0.0'

// gradle実行オプションからキーストアを取得
final exampleStorePassword = hasProperty('keystore_password') ? property('keystore_password') : ''
final exampleKeyAlias = hasProperty('key_alias') ? property('key_alias') : ''
final exampleKeyPassword = hasProperty('key_password') ? property('key_password') : ''
final exampleStoreFile = hasProperty('key_file') ? property('key_file') : ''
final examplePlayJson = hasProperty('play_json') ? property('play_json') : ''

android {
compileSdkVersion 25
buildToolsVersion "24.0.1"

  // gradle実行オプションからキーストアを取得
signingConfigs {
src {
storeFile file(exampleStoreFile)
storePassword exampleStorePassword
keyAlias exampleKeyAlias
keyPassword exampleKeyPassword
}
}
defaultConfig {
applicationId "com.sjn.demo.bitrisedemo"
minSdkVersion 14
targetSdkVersion 25
     // gradle実行オプションからバージョン情報を取得
versionCode exampleVersionCode
versionName exampleVersionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
       // gradle実行オプションからキーストアを取得
signingConfig signingConfigs.src
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.0.0'
testCompile 'junit:junit:4.12'
}

// GooglePlayサービスアカウントを設定
play {
track = 'alpha'
jsonFile = file(examplePlayJson)
}




  • gradle.properties(global)の修正


    • ローカル環境でもreleaseビルドができるようにキーストアの設定とGoogle Playのサービスアカウントの設定を追加します




gradle.properties

key_password=password

keystore_password=password
key_alias=alias
key_file=/path/to/keystore
version_code=1
version_name=0.1
play_json=/path/to/json



  • ファイルパスについては、参照されなくても正しい場所を設定しておかないとビルドエラーになるので設定が必要です。(他に方法がありそう)



  • version_code, version_nameはローカルでビルドしたものをリリースすることはないと思うので適当に設定します。


  • play_jsonは「1. Google Playのサービスアカウントのキーファイルを取得する」でダウンロードしたファイルです。

  • キーストアの参考:さぁAPKつくるか!keystore....( ゚д゚)ハッ? - Qiita



3. 確認



  1. Terminalでgradle taskを確認する

    $ ./gradlew tasks
    



  2. 以下のようなtaskが定義されていることを確認する

    Play Store tasks
    
    ----------------
    bootstrapReleasePlayResources - Downloads the play store listing for the Release build. No download of image resources. See #18.
    generateReleasePlayResources - Collects play store resources for the Release build
    publishApkRelease - Uploads the APK for the Release build
    publishListingRelease - Updates the play store listing for the Release build
    publishRelease - Updates APK and play store listing for the Release build



4. Webページからアプリをアップロードする(初回のみ)

下記の通り、最初の1回目はWebからアップロードする必要があります。

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:publishApkRelease'.
> No application was found for the package name com.example.myapplication. Is this the first release for this app? The first version has to be uploaded via the web interface.


signedApkの作成


  1. Android Studioのメニューから「Build」を選択

  2. 「Generate Signed APK...」を選択

  3. 「Next」


  4. gradle.propertiesと同様の入力をして「Next」


    ここで使うkeyStoreはBITRISEに登録するものと共通にしてください




  5. 「Finish」


  6. app以下にapp-release.apkが生成



signedApkのアップロード



  1. Google Play Developer Consoleにアクセス

  2. 「新しいアプリを追加」

  3. 「APKをアップロード」

  4. 「アルファ版テスト」

  5. 生成したapp-release.apkをアップロード


5. BITRISEにworkflowを作成する


  1. GitHubにリポジトリを作る


  2. 「Add New App」から下記のとおり設定

    参考:Android用CI環境をBitriseで構築 - Qiita



    • Connect your repository


      • 「1.」で作ったリポジトリを選択

      • 「No, auto-add SSH-Key」



    • Validation setup


      • 今回は「develop」



    • Project build configuration


      • 「Select Gradle task to run」で「assembleRelease」を選択し「confirm」



    • Webhook setup


      • 「Register a Webhook for me!」



    # privateなリポジトリだと違うかもしれないです。





  3. Workflowを修正する


    Code signing & Files

    ファイル
    内容
    備考

    キーストア
    リリース用のkeyStore
    パスワードやエイリアスを入力

    キーファイル
    「1. Google Playのサービスアカウントのキーファイルを取得する」で取得した***.json

    unique idPLAYにしました


    App Env Vars

    変数名

    備考

    GRADLE_BUILD_FILE_PATH
    build.gradle

    GRADLE_TASK
    publishApkRelease

    GRADLEW_PATH
    ./gradlew

    KEYSTORE_PATH
    $BITRISE_SOURCE_DIR/[アップしたキーストアのファイル名]
    Ex. $BITRISE_SOURCE_DIR/release.jks

    PLAY_KEY_PATH
    $BITRISE_SOURCE_DIR/[アップしたキーファイルのファイル名]
    Ex. $BITRISE_SOURCE_DIR/play.json

    GRADLE_PUBLISH_OPTION
    --stacktrace -Pkey_password=$BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD -Pkeystore_password=$BITRISEIO_ANDROID_KEYSTORE_PASSWORD -Pkey_alias=$BITRISEIO_ANDROID_KEYSTORE_ALIAS -Pkey_file=$KEYSTORE_PATH -Pversion_code=$BITRISE_BUILD_NUMBER -Pversion_name=$BITRISE_BUILD_NUMBER -Pplay_json=$PLAY_KEY_PATH


    Triggers

    タブ
    トリガー
    対象ブランチ

    PUSH
    PUSH BRANCH
    develop

    PULL REQUEST
    SOURCE BRANCH
    develop

    TARGET BRANCH
    *


    Workflow

    番号
    Work
    変更項目

    1
    Activate SSH key (RSA private key)
    変更なし

    2
    Git Clone Repository
    変更なし

    3
    Do anything with Script step
    変更なし

    4
    Update Android Extra packages
    変更なし

    5
    File Downloader
    Download source url
    $BITRISEIO_PLAY_URL

    Download destination path
    $PLAY_KEY_PATH

    6
    File Downloader
    Download source url
    $BITRISEIO_ANDROID_KEYSTORE_URL

    Download destination path
    $KEYSTORE_PATH

    7
    Gradle Runner
    Additional options for Gradle call
    $GRADLE_PUBLISH_OPTION

    8
    Deploy to Bitrise.io
    変更なし



実際に動かす


  • GitHub経由じゃなくても、画面のbuildボタンでビルド開始できます。

できました!!:tada:


BITRISE

スクリーンショット 2016-12-02 15.20.12.png


GooglePlayDeveloperConsole

スクリーンショット 2016-12-02 15.20.00.png



  • 時差がありますが、11:23のトリガーでPublishできてます。

  • bitriseのbuild番号に対応したアプリバージョンになってます。

  • α版のテストが終わったら画面からβ版にプロモートします。



以上で、労力をかけずに常に最新版のアプリをテスターに配布できるようになりました!

アプリ配布を自動化することで開発に集中できます :innocent:

最新のアプリのフィードバックをもらい顧客に届く価値をドンドン増やしていきましょう!!!!