Androidのビルドとテストをwerckerで自動化する

## はじめに

[前回](http://qiita.com/cattaka/items/16fa27189c865254b528)のAndroidでコードカバレッジがどんな感じで測れるのかに続き、今回はビルドからテストまでwerckerで自動化する方法をご紹介します。

なお、werkcerのオフィシャルのAndroidのドキュメントはこちらです。

- http://wercker.com/android/


## サンプルアプリ

前回と同じく、使用しているアプリは次のURLで公開しています。

- https://github.com/cattaka/FastCheckList

ソースコードの取得には次の様にgitコマンドを使用して取得してください。

```bash
$ git clone https://github.com/cattaka/FastCheckList.git
```

なお、サンプルアプリのビルドの成果物は次のURLにデプロイしています。

- http://www.cattaka.net/wercker/fastchecklist/


## werckerとは

werckerとはTravis CIのようなCIのサービスの一種です。2015/01/04現在はbeta版で無償で利用することができます。GitHubのようなリポジトリにソースコードを置き、フックや設定ファイルの設定を行なっておくと、テスト、ビルド、デプロイまでを行なうことができます。ビルドはboxと呼ばれる仮想環境で行われます。テスト、ビルド、デプロイはbox上で行われます。

### box(仮想環境)

boxは仮想環境で、OSや各種ビルド用のツールがインストールされたもので構成されます。Androidアプリをビルドする場合はAndroid SDKもこれらに含まれます。エミュレーターも含まれます。
boxは公開されているものを使用することができますが、自分で作成することができます。公開されているものはwercker公式のものもありますが、他の人が作成したものもあります。自分で作成した場合、同じように公開され、他の人が使えるようになります。

### ソースコードはgithubなどから取得する

ソースコードはgithubやBitbucketから取得することができます。プライベートリポジトリも各種Keyを適切に設定すれば使用できます。

### boxの実行

boxが起動するとビルドなどが始まるのですが、これらはpipeline、stepという概念で構成されます。pipelineにはBuildフェーズとDeployフェーズの２つがあります。１つのフェーズは複数のstepで構成され、stepには任意の処理を行わせることができます。
テスト、ビルド、デプロイといったものは、このstepの１つ１つに対応させるイメージになります。

### 成果物の取得

基本的に成果物はデプロイして特定のサーバーに反映をすると思いますが、環境変数の$WERCKER_REPORT_ARTIFACTS_DIRで示されるディレクトリにコピーしておくと、artifacts.tar.gzに保存され、ダウンロードできるようになります。


## box

boxはビルドやテストを行なう場合の仮想環境です。公開されているものを使うこともできますし、自分で作ることもできます。

### boxの選び方

boxは次のURLで検索することができます。

- https://app.wercker.com/#explore/boxes

ここにはAndroid用だけでなく、RubyやGo言語用のboxが表示されています。絞り込みのキーワードに"android"と入れると良いでしょう。選んだboxは後述のアプリのwercker.ymlで指定します。

### boxを選ぶ時の注意点

boxを選ぶ際にはboxにインストールされている次のもののバージョンに注意してください。

- Android SDK Toolsのバージョンをアプリのbuild.gradleに合ってること
- Android SDK Build-toolsのバージョンをアプリのbuild.gradleに合ってること
- SDK Platformのバージョンをアプリのbuild.gradleに合ってること
- エミュレーターのバージョンがアプリのwercker.yml(後述)に合っていること

もしこれらのバージョンが食い違っていると、漏れ無くビルドに失敗するのでご注意ください。これらのバージョンは各boxのReadmeに書かれていると思うので、それを参考にすると良いでしょう。ただし、Readmeが更新されていなくて嘘を書いているものもあるのでご注意ください。念を入れて確認するにはboxを作る元になる設定ファイルのリポジトリへのリンクが、boxのページにありますので、そこからリンクを辿って設定ファイルを確認すると良いでしょう。
もし丁度良いバージョンがない場合はforkして設定ファイルを書き換え、自分用のboxを作ることもできます。


## werckerにアプリを登録する

アプリを登録するのは至ってシンプルです。登録に必要なことは次のようになります。

− werckerのAppsのAddからGitHubのリポジトリを登録する
- wercker.ymlを作成する
- パスワードなどを環境変数で指定する
- デプロイ先を設定する

### werckerのAppsのAddからGitHubのリポジトリを登録する

werkcerのAppsのAddから追加できます。画面に従って操作すれば登録が完了します。
この際にGitHub側のWebhooksも一緒に設定されます。

![image](https://qiita-image-store.s3.amazonaws.com/0/55138/eae44c22-2d7e-d485-a52b-73e286180606.png)

### wercker.ymlを作成する

wercker.ymlはアプリのリポジトリのルートに配置します。
サンプルアプリで使用しているwercker.ymlは次のようになります。

```yaml
box: cattaka/android@1.0.8-r1
build:
  steps:
    - script:
        name: show base information
        code: |
          gradle -v
          echo $ANDROID_HOME
          echo $ANDROID_SDK_VERSION
          echo $ANDROID_BUILD_TOOLS
          echo $ANDROID_UPDATE_FILTER
    - android-sdk-update:
        filter: sysimg-21
    - setup-android-emulator:
        target: android-21
    - script:
        name: run gradle createDebugCoverageReport
        code: |
          gradle --project-cache-dir=$WERCKER_CACHE_DIR createDebugCoverageReport
    - script:
        name: run gradle assembleDebug
        code: |
          pwd
          gradle --full-stacktrace -q --project-cache-dir=$WERCKER_CACHE_DIR assembleDebug
  after-steps:
    # Use the build results
    - script:
        name: inspect build result
        code: |
          pwd
          ls -la ./app/build/outputs/
          cp -r ./app/build/outputs/* ${WERCKER_REPORT_ARTIFACTS_DIR}
deploy:
  steps:
    - script:
        name: upload to www.cattaka.net
        code: |
          lftp -u ${DEPLOY_FTP_USER},${DEPLOY_FTP_PASS} -e "set ssl:verify-certificate no;mirror --delete -R ./app/build/outputs/ fastchecklist/;quit" ${DEPLOY_FTP_SERVER}
```

scriptと書かれているstepではシェルスクリプトとして幾つかのコマンドを実行しています。
特にcreateDebugCoverageReportやassembleDebugは以前の記事で紹介した、自動テストを行ったり、ビルドを行なうコマンドです。
各stepで行なっていること簡単に説明すると次のようになります。

- buildのsteps
 - script:show base information よくトラブルの原因になるのでバージョンやディレクトリをログに出力しています
 - android-sdk-update Android SDKのバージョンを設定に合わせて更新しています
 - setup-android-emulator 自動テストのためのエミュレーターを起動しています(たまにコケます、、、)
 - script:run gradle createDebugCoverageReport 自動テストとカバレッジレポートの作成を行います
 - script:run gradle assembleDebug デバッグ用APKを作成しています
- buildのafter-steps
 - script:inspect build result 後からダウンロードできるように成果物フォルダにコピーしています
- deployのsteps
 - steps:upload to www.cattaka.net 成果物をFTPでサーバーにアップロードしています


### パスワードなどを環境変数で指定する

wercker.ymlはリポジトリに格納する都合上、中身にパスワードを直接指定するのは好ましくないでしょう。この問題を回避するためにwercker.ymlには環境変数が利用できます。
前述のwercker.ymlの "steps:upload to www.cattaka.net" のところに現れていますが、\${DEPLOY_FTP_USER}や\${DEPLOY_FTP_PASS}、\${DEPLOY_FTP_SERVER}がそれに該当します。
これらはwerckerのAPPのSettingsから指定することができます。変数名と値の組み合わせで指定できます。ここにはProtectedといったチェック項目があり、チェックするとログには表示されなくなるといった配慮がなされます。

![image](https://qiita-image-store.s3.amazonaws.com/0/55138/6abbb674-a8fe-92fc-36c7-89fe2b5dc923.png)


### デプロイ先を設定する

wercker.ymlのdeployのstepsで指定されたものは、何もしなければ実行されません。SettingsのDEPLOY TARGETで少しだけ設定が必要になります。
設定する内容は単純に２つでデプロイ先の名前と、どのブランチでビルドしたものなら自動的にデプロイするのかです。

![image](https://qiita-image-store.s3.amazonaws.com/0/55138/97a85bdb-3103-0f8f-dab2-8a7fb1ccc98c.png)


## ビルドとデプロイを実行する

ビルドの実行は難しくありません。GitHubにいつもどおりpushすれば、そこからhookされ、自動的にwercker上でビルドが実行されます。また、デプロイ先の設定で自動的にデプロイに指定されたブランチの場合、自動的にデプロイまで行われます。

なお、JUnitの作り方の問題であったり、エミュレーターが起動に失敗したりで偶発的にビルドにコケる時があります。この場合は手動でREBUILDを押してあげましょう。

## 現状の問題点

werckerがあれば何でもできそうですが、現状でいくつかの問題点がわかっています。

### Keystoreをどこに保持させるか

実は今回の記事ではデバッグ用APKに留めて、リリース用APKについては触れていません。これには署名用キーをどうするかという問題が解決していないからです。署名用のキーはリポジトリに入れるわけにもいれず、どこかからダウンロードするにも何処に置くかが悩ましいです。HEX化して環境変数に捩じ込むことも考えているのですが、今の段階では未解決です。

### エミュレーターがたまにコケる

wercker.ymlのsetup-android-emulatorのstepでたまにコケます。原因はまだわかってません、、、

### エミュレーターが割と遅い

2014/01/04現在ではエミュレーターはARMのものしか動作せず、x86のものは動作しません。このため速度が遅く、JUnitのテストケースの数が多い場合にビルド時間が長くなってしまいます。


## おわりに

いかがだったでしょうか。werckerでAndroidのビルドとテストがどのように自動化されるかが伝わりましたでしょうか。
ご興味を持たれた方はサンプルアプリをforkして実際にwerckerに登録して動かして見ていただければと思います。

次回は今回触れなかったboxの作り方をご紹介できればと思います。