57
58

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Androidで社内リリースの自動化

Last updated at Posted at 2016-05-17

はじめまして。FiNCでAndroid Applicationを開発している南里です。
Androidアプリ全般の設計と実装を行っています。
インターンとして2年前くらいに加わり、そのまま新卒社員として入社しました。
ちょうどその頃からバイソンと呼ばれたりもしています。
急速に拡大するプロジェクトで生じたチーム開発の問題点とAndroidチームが行った対処法についてお話したいと思います。

プロジェクトの拡大による問題点とその対策

FiNCはヘルスケアのアプリ(Web, iOS, Android)を開発しています。
ここ1年ほどでプロジェクトが急速に拡大し、エンジニアの数も約4倍に増えました。
そこで出てきた大きな問題点がコミュニケーション量の爆発的増加です。
中でも、実際に実装した機能と、プロジェクトツール上で確認できる機能のステータスが一致しないといった、
実装機能のチェック時のコミュニケーションロスと1日に複数回の社内配信を手動で実施しているという2つの問題がありました。
そこで、マージ済のコミットを自動的に収集し、開発アプリの社内配信とリリースノートの自動化を行うことにしました。

アプリの自動化

  • CicleCIとFabricを用いた配信の自動化
  • リリースノートの自動化

開発環境

  • Android Studio(おなじみGradle)
  • Git, Github
  • CircleCI

全体構成

Kobito.eKDEmD.png

実装

手順は以下です。

1. Fabricを導入する(初期設定)

2. build.gradleをカスタマイズする。(配信のカスタマイズ)

3. CircleCI設定を行う。(トリガーの設定)


### 1. Fabricの導入(初期設定) FabricとはTwitter社が提供しているプラグインで、もろもろ機能が利用できるパッケージです。 このパッケージが内包している、Crashlytics(バグのレポートに良く使います)の中のBetaという配信機能を利用します。

まず、AndroidにFabricプラグインをインストールします。
(PreferenceのPluginにあります。)

Android Studioのツールバーにて、以下のアイコンが表示されるようになります。
(右から3番目。ここから配信します。)
スクリーンショット 2016-05-16 1.13.20.png

実際の実装に関しては、公式ホームページ
に書いてあります。
初期化はアプリケーションクラスに書きます。

Application.java
// Set up Crashlytics, disabled for debug builds
Crashlytics crashlyticsKit = new Crashlytics.Builder()
    .core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build())
    .build()

// Initialize Fabric with the debug-disabled crashlytics.
Fabric.with(this, crashlyticsKit);

### 2. build.gradleをカスタマイズする。(配信のカスタマイズ) GradleとはGroovyのDSLを利用したビルドシステムのことで、Android Studioに標準で採用されています。

・タスク一覧の確認

手順1でCrashlyticsを導入するとgradleにタスクが追加されています。
プロジェクトのrootでgradle tasksと打ちます。

Kobito.GfFnav.png

crashlyticsで始まるタスクが4つ追加されています。
Distributionの後にはapkファイルの名前が表示されています。
もっというと、Build Variantsがそのまま表示されるようになっています。

Build Variantsとは"Product Flavor"と"Build type"の組み合わせで、最終的なapkファイルはここを元に作成されます。
上記の場合、以下の4パターンのapkファイルが作成できます。

apk Product Flavor Build Type
apk1 production release
apk2 production debug
apk3 staging release
apk4 staging debug

このタスクはビルド済みのapkファイルをBetaにアップロードするタスクです。
成功すると、Fabricのページで配信状況を確認できるようになります。

・配信の設定

また配信グループリリースノートを指定するためにはmanifestPlaceHoldersに追加します。

build.gradle
productFlavors {

    staging {
        manifestPlaceholders = [
           // 配信グループの指定
            ext.betaDistributionGroupAliases = "team_name" // groupsにaliasが表示されているので、それを利用
            // リリースノートの指定
            ext.betaDistributionReleaseNotes = getLatestCommitMessage() // 最新のコミットメッセージを取得
        ]    
    }

    production {
    }
}

最新のメッセージを取得する部分は以下に切り出し。
ファイル切り出したほうがいい気がしますが、今回はやっていません。

・リリースノート作成

  1. 最後の配信日時がrelease_note.txtに記載されているので、その日時を取得(なければ、タスク終了後に追加)
  2. 前回配信からの差分取得
  3. 配信日時の更新
// 更新されたコミットを取得し、配信日時を更新
def getLatestCommitMessage() {
   // 最新配信日時を取得する。その情報はrelease_note.textに格納。
    def lastDistributedDate = new File("${project.rootDir}/release_note.txt").text.trim()
   // 最後のマージ日時からの差分コミットの取得 
    def gitLog = ["sh", "-c", "cd ${project.rootDir} ; git log マージ先ブランチ --pretty=format:\'%cn: %s\' --after=\'$lastDistributedDate\'"].execute().text
    // 最新のコミットの時刻を取得
    def updateCommit = ["sh", "-c", "cd ${project.rootDir} ; git log マージ先ブランチ -1 --format=\'%cI\'"].execute().in.text.trim()
    // release_note.txtに記載されている日時の更新
    def updateDate = new File("${project.rootDir}/release_note.txt")
    updateDate.write(updateCommit);
    // 何もない場合は
    if (gitLog.trim().length() > 0) return (gitLog)
    return 'git log -n 1'.execute().text
}

もし上記 git commandの部分でうまくいかなければ、CicleCIにsshで繋いで確認できます。(CircleCIのGUIから可能)

3. CircleCI(トリガーの設定)

CicleCIとはビルド、テストなどをトリガー発火で継続的に実行することです。
すぐ導入するためのコードも書いてます。易しいCircle Ci for Android

CircleCIがGithubにおいて、マージされたタイミングでCIが走り、テスト、ビルドが完了するとアプリが配信されます。

以下はそのまま適用できると思いますが、
deploymentのところにマージ先のブランチ名とその際に実行するタスクを追加します。
./gradlew crashlyticsUploadDistributionStagingDebuggradle tasksで確認できるもののいずれかを書きます。(もちろん配信環境に合わせて)

circle.yml
machine:
    java:
        version: openjdk7 # デフォルトはopenjdk7
    environment:
        ANDROID_HOME: ~/Applications/android-sdk-macosx # なくてもよい。                                                                                                     

dependencies:
    override:
        - echo y | android update sdk --no-ui --filter "android-23, build-tools-23.0.1" # デフォルトで導入されているパッケージは入れる必要なし。下記参照
test:
    override:
        - ./gradlew test
deployment:
    develop:
        branch: マージ先ブランチ名
        commands:
            - ./gradlew assembleDebug、
            - ./gradlew crashlyticsUploadDistributionStagingDebug # マージ先ブランチがdeployされたタイミングで実行されるタスク

上記の設定をすることによって、誰でも簡単にアプリを配信し、リリースノートをQAに伝達することが可能になります。

Kobito.7R6LMT.png

うまくいきました。(内容はマスクしてます。)
補足ですが、上記リリースノートは実装者の名前PRのタイトルを出すようにgit logをカスタマイズしています。
PRのタイトルにJIRAのチケットのurlを貼るオペレーションさえ徹底すれば、QA担当者が最適に作業しやすい状態を作れてみんな幸せになります。
(こちらの運用は圧倒的にミスが少なくなりました。)

最後に

プロダクトの規模が拡大するにつれて、いかに属人化をなくし、効率化を進めていくかということはこれからも直面し続ける課題になると思います。
Androidエンジニアの南里でした!

57
58
1

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
57
58

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?