Jenkins + Android + SonarQube (旧 Sonar) で一歩進んだ自動テストな CI 環境を構築する パート1

Jenkins だけでなく Sonar も使用した場合のまとまった記事がないとなげきの声が散見されるので僕自身の備忘録も込めてセットアップ方法を簡単にまとめてみます。(例によって書き殴りとなるでしょう)

Maven+Jenkins+Sonar の環境構築手順については、若干古いバージョンの例ですが、Maven,Jenkins,Sonarの導入手順にまとまっているので、このエントリでは Android アプリ開発向けのナレッジを加味してその辺を含めてちょっと記載していこうと思います。

っとその前に Sonar て何?って方は コード探知機「Sonar」でプロジェクトの深海を探れ! を見てみて下さい。正直な話、テスト結果を含むコード品質については Jenkins だけでは役不足感が否めないので Sonar の導入を強くお勧めします。尚 Sonar の公式サイトではどのような情報が把握できるのか実際に デモ を見ることができるので参考にしてみて下さい。


これからインストールする主なソフトウェアは以下の通りです。

それでは早速解説して参ります。下記コマンド記載は思い出しつつ記載しているので間違っているところなどあるかもしれません。また${HOME}は適宜読替えて下さいませ。恐らく Mac でも Windows でも環境構築は可能ですがコマンド例は Linux となっていますのでプラットフォームが異なる場合は適宜読替えて下さい。
尚、tar 形式や zip 形式のミドルウェアを導入している理由は、バージョンアップや切り戻しの容易性のためです。また各ミドルウェアは基本的に $home 直下に配置するようにしています。これも管理の容易性のためです。(インストールの容易性よりもメンテの容易性の方が重要なので)

JDK

入手先:http://www.oracle.com/technetwork/java/javase/downloads/index.html
SonarQube (旧 Sonar) のシステム要件などから OracleJDK を使用します。このエントリでは紹介しませんが、Mavenリポジトリ管理に Sonatype Nexus を使いたいとかあるかもしれないので、最新の JDK7 の使用をおすすめします。Jenkins で Android プロジェクトのビルドには JDK6 を使いたい!! というこだわりがあれば JDK7 と JDK6 の両方を入れて下さい。尚、JRE ではなく JDK を使用するのは Android SDK などいくつかのプロダクトが JDK を要求しているのと、ケースバイケースで JRE / JDK を使い分ける説明が混乱を招く恐れがあることからです。


$ tar zxvf jdk-7u25-linux-x64.tar.gz
$ mv jdk1.7.0_25 ${HOME}
$ rm -f jdk-7u25-linux-x64.tar.gz

※注:JAVA_HOME は Tomcat の setenv.sh や Jenkins で設定するので .bashrc や .bash_profile には書かずに進めます。

Tomcat

入手先:http://tomcat.apache.org/download-70.cgi
システム要件から Jetty か Tomcat を使用することになるかと思います。このエントリでは Tomcat を導入します。執筆時点の最新は 7.0.42 です。


$ cd $home
$ wget http://www.us.apache.org/dist/tomcat/tomcat-7/v7.0.42/bin/apache-tomcat-7.0.42.tar.gz
$ tar zxvf apache-tomcat-7.0.42.tar.gz
$ rm -f apache-tomcat-7.0.42.tar.gz

Tomcat 起動時の環境設定用ファイル setenv.sh (Windows の場合は setenv.bat) を作成して、JAVA_HOME の設定と CATALINA_OPTS で server モードの指定をします。

vi ${HOME}/apache-tomcat-7.0.42/bin/setenv.sh
#!/bin/sh

# JDK7を指定して下さい。
export JAVA_HOME=${HOME}/jdk1.7.0_25

CATALINA_OPTS="-server"
CATALINA_OPTS="${CATALINA_OPTS} -Djava.awt.headless=true"
CATALINA_OPTS="${CATALINA_OPTS} -Dorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true"

# 以下は例なので環境に合わせて適宜変更して下さい

# Sonar を入れるので PermSize は 256m 以上取って下さい。
CATALINA_OPTS="${CATALINA_OPTS} -XX:PermSize=256m"
CATALINA_OPTS="${CATALINA_OPTS} -XX:MaxPermSize=256m"
# Sonar のシステム要件。512m 以上
CATALINA_OPTS="${CATALINA_OPTS} -Xms512m"
CATALINA_OPTS="${CATALINA_OPTS} -Xmx768m"

CATALINA_OPTS="${CATALINA_OPTS} -XX:NewRatio=2"
CATALINA_OPTS="${CATALINA_OPTS} -XX:+UseConcMarkSweepGC"
CATALINA_OPTS="${CATALINA_OPTS} -XX:+CMSParallelRemarkEnabled"
CATALINA_OPTS="${CATALINA_OPTS} -XX:+UseParNewGC"
CATALINA_OPTS="${CATALINA_OPTS} -XX:MaxTenuringThreshold=32"
CATALINA_OPTS="${CATALINA_OPTS} -XX:SurvivorRatio=8"
CATALINA_OPTS="${CATALINA_OPTS} -XX:TargetSurvivorRatio=90"
CATALINA_OPTS="${CATALINA_OPTS} -XX:+DisableExplicitGC"

export CATALINA_OPTS

Jenkins を導入した際に Tomcat へ URIEncoding="UTF-8" の指定をしろと警告がでるので、先に HTTP コネクタ (8080) に同設定を追加します。また Apache 連携しないので AJP コネクタ (8009) をコメントアウトします。

vi ${HOME}/apache-tomcat-7.0.42/conf/server.xml
:中略
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443"
               URIEncoding="UTF-8" />
:中略
<!-- 
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
 -->
:中略

ここで1度 Tomcat が起動できることを確認しておきます。


$ cd ${HOME}/apache-tomcat-7.0.42/bin
$ ./startup.sh
$ # tail コマンドでログを見て起動を確認 (Ctrl + C で抜けます)
$ tail -f ../logs/catalina.out

起動確認できたら Tomcat を停止します。


$ cd ${HOME}/apache-tomcat-7.0.42/bin
$ ./shutdown.sh
$ # ps コマンドで停止を確認
$ ps aux|grep java

Jenkins

入手先:http://jenkins-ci.org/
jenkins.war ファイルをダウンロードして Tomcat の webapps へコピーまたは移動します。


$ cd $home
$ wget http://mirrors.jenkins-ci.org/war/latest/jenkins.war
$ mv jenkins.war ${HOME}/apache-tomcat-7.0.42/webapps

Ant

入手先:http://ant.apache.org/bindownload.cgi
Jenkins で Ant が使えるように『一応』 Ant もインストールしておきます。※本連載では使いませんのでインストールは任意でかまいません。


$ cd $home
$ wget http://www.us.apache.org/dist//ant/binaries/apache-ant-1.9.2-bin.tar.gz
$ tar zxvf apache-ant-1.9.2-bin.tar.gz
$ rm -f apache-ant-1.9.2-bin.tar.gz

Maven

入手先:http://maven.apache.org/download.cgi
本構成の要である Maven をインストールします。執筆時点の最新は 3.1.0 です。
Jenkins は 1.526 から Sonar は 3.7 から Maven 3.1.0 に対応しましたが、Android のビルドに使う Mavenプラグインである android-maven-plugin (執筆時点の最新は 3.6.1) は Maven 3.1.0 に対応していないので Maven 3.0 系の最新である 3.0.5 を使います。


$ cd $home
$ wget http://www.us.apache.org/dist/maven/maven-3/3.0.5/binaries/apache-maven-3.0.5-bin.tar.gz
$ tar zxvf apache-maven-3.0.5-bin.tar.gz
$ rm -f apache-maven-3.0.5-bin.tar.gz

Android SDK

入手先:http://developer.android.com/sdk/index.html
SDK Tools Only の Android SDKをインストールして update sdk を実行します。※ライセンスを問い合わせられるので "y" を入力して進めて下さい。


$ cd $home
$ wget http://dl.google.com/android/android-sdk_r22.0.5-linux.tgz
$ tar zxvf android-sdk_r22.0.5-linux.tgz
$ rm -f android-sdk_r22.0.5-linux.tgz
$
$ cd android-sdk-linux/tools
$ ./android update sdk -u

SonarQube (旧 Sonar)

入手先:http://www.sonarqube.org/
執筆時点の最新である 3.7 を導入します。


$ cd $home
$ wget http://dist.sonar.codehaus.org/sonar-3.7.zip
$ unzip sonar-3.7.zip

次に Sonar の設定ファイルを編集します。SonarTomcat 経由で使うので公式の手順通り以下の様に変更します。
※他にも接続するデータベースの設定変更などが可能です。デフォルトでは H2 という Sonar に組込み済のデータベースを使用する設定となっています。評価向けであれば、まずは H2 で問題ないです。


vi ${HOME}/sonar-3.7/conf/sonar.properties
:中略
sonar.web.host: localhost
sonar.web.port: 8080
sonar.web.context: /sonar
:中略

Sonar の設定変更が完了したら war ファイルをビルドします。


$ cd ${HOME}/sonar-3.7/war
$ ./build-war.sh

war ファイルが生成されたら Tomcat の webapps へコピーまたは移動します。
Sonar の設定を変更したり JDBC ドライバを変更した場合は、再度 war をビルドして Tomcat へ配布して下さい。


$ mv ${HOME}/sonar-3.7/war/sonar.war ${HOME}/apache-tomcat-7.0.42/webapps

ここまでで土台となるミドルウェアのインストールは完了です。次からは各ミドルウェアのセットアップをして参ります。まずは Tomcat を起動して Jenkins や Sonar の管理画面へアクセスできるようにします。(Tomcat の起動方法は先の手順を参照して下さい)
尚、Sonar の初回起動時はデータベースのテーブル作成などが行われるため、Tomcat の catalina.out にそれらのログが出力されます。

Jenkins へプラグインをインストールする

  • 利用可能なプラグイン画面を表示します。
  • 一覧から "Android Emulator Plugin"、"Jenkins Sonar Plugin" にチェックを入れ、"再起動せずにインストール"ボタンを押下します。(※依存関係のある他のプラグインも一緒にダウンロードされます。)
  • すべてのプラグインがダウンロードされたら Tomcat を再起動して下さい。

※必要があれば Subversion プラグインや Git プラグインなども入れて下さい。

Jenkins を設定する

キー ANDROID_HOME
(※Android SDKを配置した場所。例: /home/orangesignal/android-sdk-linux)

Android SDK root ${ANDROID_HOME}

  • JDKを設定します。※JDK6を使いたい場合はJDK6のパスや名前を設定して下さい。
名前 jdk1.7.0_25
JAVA_HOME (※JDKを配置した場所。例: /home/orangesignal/jdk1.7.0_25)
自動インストール オフ

  • Antを設定します。
名前 apache-ant-1.9.2
ANT_HOME (※Antを配置した場所。例: /home/orangesignal/apache-ant-1.9.2)
自動インストール オフ

  • Mavenを設定します。
名前 apache-maven-3.0.5
MAVEN_HOME (※Mavenを配置した場所。例 /home/orangesignal/apache-maven-3.0.5)
自動インストール オフ

  • "Sonar"セクションの"高度な設定"ボタンを押下してSonarプラグイン設定をすべて表示します。
  • このセクションではSonraのsonar.propertiesの内容と整合するように値を入力します。
名前 sonar (何でも良い)
Server URL http://localhost:8080/sonar
Database URL sonar.propertiesのsonar.jdbc.urlの値と同じ
Database login sonar.propertiesのsonar.jdbc.usernameの値と同じ
Database password sonar.propertiesのsonar.jdbc.passwordの値と同じ
Database driver H2の場合はブランクでOK、それ以外の場合は右の?を押下してヘルプ参照のこと
Version of sonar-maven-plugin 2.1 ※恐らくブランクでも問題ないが執筆時点での最新プラグインを使って欲しいので指定しています


Sonarプラグインをインストールする

Android 用の品質プロファイルを作成する

  • Android Lint 欄の右側にある "コピー" を押下します。
  • 新しい名称として新規の品質プロファイル名 (例:Android) を入力し "コピー" ボタンを押下します。

  • プロファイル一覧にて上記で作成したプロファイル名のリンクをクリックします。

  • プロファイルの継承 (inheritance) タブを押下します。

  • 右側の親プロファイルの設定から "Sonar way with Findbugs" を選択し"変更"ボタンを押下します。


※必要があればコーディング規則タブで、標準では無効になっている PMD の Android 向けルールや、CheckStyle の Comment pattern matcher ルールなどを有効にして下さい。

※この Sonar 環境を Android 以外の Java プロジェクトで使用する予定がなければ、プロファイル画面で潔く"デフォルトに設定"をすることで pom.xml や Jenkins ジョブ側でプロファイルを指定する手間が減ります。

Android SDKMavenリポジトリへ登録する

GitHubmaven-android-sdk-deployer をダウンロードして、How to Use の手順通り Android SDK 一式を Maven のローカルリポジトリへ登録します。


$ cd $home
$ unzip maven-android-sdk-deployer-master.zip
$ cd maven-android-sdk-deployer-master
$ export ANDROID_HOME=${HOME}/android-sdk-linux
$ ${HOME}/apache-maven-3.0.5/bin/mvn install
$ rm -r maven-android-sdk-deployer-master
$ rm -f maven-android-sdk-deployer-master.zip

ミドルのセットアップはこれで準備完了です。Android 用プロジェクト& Jenkins ジョブ設定は次回へ