リア充爆発日記

You don't even know what ria-ju really is.

さくらのVPS+Jenkins+github+Android

さくらのVPS+Jenkins+github+rails3の続編。

ゴールは、githubにpushすると、さくらのVPSで動いているJenkinsがgithubから最新ソースひっぱってRobolectricのテストかけた上に、apkを作るところまで。

プロジェクトの作成

mavenプロジェクトにしてみた。

ユーザーの作成

以前作ったやつで兼用。

SSH key

コレも兼用しようと思ったらダメだった。1リポジトリにつき1keyだそうで。
https://help.github.com/articles/error-key-already-in-use

Once a key has been attached to one repo as a deploy key, it cannot be used on another repo. If you're running into this error while setting up deploy keys, check out this guide for more details.

まあ、同じものを名前変えて作るだけです。

・・・と作るのはいいけど、どうやって2つのキーを使い分けるんだろう?
と.ssh/configだった。

Host github-HOGE
 HostName github.com
 User git
 IdentityFile /var/lib/jenkins/.ssh/id_rsa_HOGE

Host github-FUGA
 HostName github.com
 User git
 IdentityFile /var/lib/jenkins/.ssh/id_rsa_FUGA

まあ、名前は適当でいいので。

で、これまでgit@github.com:USERNAME/HOGE.gitとかでアクセスしてたのをgit@github-HOGE:USERNAME/HOGE.gitでアクセスすればOK。
Jenkinsのconfigも書換えて置く。


この時点でgithubからcloneできるはずなので、Jenkinsの管理画面からBulid nowする。cloneはできたけど、pomでapkがunknownでどうたらというエラー。おお。もうpomをどうたらしようとしてるのか。で、次はどうすればいいんだ。っていうか、jenkins抜きにしてテストが動くようにしないとダメね。


さくらのVPSでRobolectricのテスト環境を作る

というテーマになった。

過去の軌跡を振り返りながら、ここはひたすら頑張る。
http://d.hatena.ne.jp/ria10/archive?word=maven

JDKをインストール

さくらのVPSCentOSは64bitでAndroidが1.6だからjdk-6u38-linux-x64-rpm.binでいいかな。。。
これは落としてきて普通にrootで実行するだけ。wgetで落とせるパスを探すのがめんどくさかったので一度ローカルに落として、そこからscpであげたお・・・。

環境変数の設定

vi /etc/profile.d/jdk.sh

export JAVA_HOME=/usr/java/default
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/jre/lib:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar

mavenをインストール。

もうほぼここを丸パクで。
http://xmodulo.com/2012/05/how-to-install-maven-on-centos.html

$ wget http://mirror.cc.columbia.edu/pub/software/apache/maven/maven-3/3.0.4/binaries/apache-maven-3.0.4-bin.tar.gz
$ sudo tar xzf apache-maven-3.0.4-bin.tar.gz -C /usr/local
$ cd /usr/local
$ sudo ln -s apache-maven-3.0.4 maven
$ sudo vi /etc/profile.d/maven.sh

export M2_HOME=/usr/local/maven
export PATH=${M2_HOME}/bin:${PATH}

最初なのでsourceしておく。

$ mvn -version
Apache Maven 3.0.4 (r1232337; 2012-01-17 17:44:56+0900)
Maven home: /usr/local/maven
Java version: 1.6.0_38, vendor: Sun Microsystems Inc.
Java home: /usr/java/jdk1.6.0_38/jre
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "2.6.32-279.14.1.el6.x86_64", arch: "amd64", family: "unix"

調子良さげ。


あれ?Jenkinsがまたアップデートだしてる、っていうかこういうペースなのね。。
yum updateでアップデートできた。yumでインストールしたんだっけ?まあいいや。

Android SDKのインストール

http://dl.google.com/android/android-sdk_r21.0.1-linux.tgz
ここからとってきて、解凍して適当なところに置くだけ。今回は/usr/local/android-sdk-linuxに配置した。

vi /etc/profile.d/android-sdk.sh

export ANDROID_HOME=/usr/local/android-sdk-linux
export PATH=$PATH:/usr/local/android-sdk-linux/platforms
export PATH=$PATH:/usr/local/android-sdk-linux/tools

source /etc/profile

# download all api
android update sdk --no-ui

Maven Android SDK Deployerのインストール

セントラルリポジトリにないAndroidライブラリはMaven Android SDK Deployerでインストール
特記事項無し。

こんなとこかな・・・。

ここまでの作業をAndroid Maven Pluginを入れてMavenでAndroidをビルドで使ったサンプルをダウンロードして動作確認してみる。

cd /tmp
wget https://github.com/jayway/maven-android-plugin-samples/zipball/stable #変な名前でDLされちゃったからこのあとリネームした。
unzip maven-android-sample.zip
cd jayway-maven-android-plugin-samples-b17572a/apidemos-android-10
mvn clean install

~snip~
/usr/local/android-sdk-linux/platform-tools/aapt: /lib/libz.so.1: no version information available (required by /usr/local/android-sdk-linux/platform-tools/aapt)
~snip~
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] Android SDK ApiDemos - Parent ..................... SUCCESS [0.555s]
[INFO] Android SDK ApiDemos - Application ................ SUCCESS [1:02.501s]
[INFO] Android SDK ApiDemos - Instrumentation Test ....... FAILURE [3.141s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
~snip~

おお。けっこういいセンいってるじゃん。

で "lib/libz.so.1: no version information available"が何かって話か。。。調べるとzlibのバージョンかアーキテクチャが合ってないときに起きるらしい。アーキテクチャは32bitで問題なさそう。バージョンはよくわからんから、最新のをインスコしてみる。

ふつうにやると64bitになっちゃうのでオプションを指定しておく。

$ export CC="gcc -m32"
$ export LD="gcc -m32"

$ ./configure
$ make
$ make install

$ file /usr/local/lib/libz.so.1.2.7
/usr/local/lib/libz.so.1.2.7: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, not stripped

良い感じ。
で、lib/libz.so.1はシンボリックリンクなのでいまインストールしたやつにリンクを張り替える。

ちなみに、このビルドで

/usr/include/gnu/stubs.h:7:27: error: gnu/stubs-32.h: そのようなファイルやディレクトリはありません

って言われたから以下のRPMを入れた。

sudo yum install glibc-devel.i686


で、再度実行かけたら、

Found 0 devices connected with the Android Debug Bridge

って言われてこけたけどこれはこれでいいんじゃないのかな。エミュレータ動いてないから。エミュレータと連携させたテストは今回はスコープ外なので先に進んでみる。


ローカルでmaven clean installが通るようにする

前もどこかで書いたけど、IntelliJmavenの両方でうまくいく方法がわからなかったから、今回はJenkins用に別POMを作ってそれを指定してやることにした。かなり重複するので、いつかなんとかしたいけど、今はとりあえずこの方法で。



ここはプロジェクトごとにやり方がまったく違うと思うので基本的に割愛するけど、いちおうハマった点をいくつか。

  • 文字コードの問題でテストがこける。
  • maven testで使いたいライブラリが別のライブラリに食われる
    • SupportLibraryで起きたんだけど、こちとらr11を使いたいのにRobolectricがr6だかなんだかを使っていてそっちに食われているのに気づくのにだいぶかかった。maven3なら単純に使いたいライブラリを先に記述しておけばOK。あと、そういうときはコメントしておいたほうがいい。おれなんてかっこいいから英語でしてみた。他の人のやつをコピペしてちょっと書き換えただけだけど。
    <dependencies>
        <dependency><!-- Make sure this is above the robolectric -->
            <groupId>android.support</groupId>
            <artifactId>compatibility-v4</artifactId>
            <version>11</version>
        </dependency>
~snip~
    </dependencies>
  • dex時にライブラリがかぶってIllegalArgumentException: already added:
    • ActionBarSherlockとか使ってるとSupportライブラリのせいでこれに該当する。
      • ActionBarSherlockが読み込んでいるのを削除して、どこかのに統一させる
      • ActionBarSherlockをMavenで読み込んでいる場合は、ABSのpomを書き換える。
        • ただこれ、もっといい方法ないのかなぁ。これだと環境が変わったりしたときに同じ問題に遭遇しちゃうんだよね。。いい方法ある気がするんだけど。。

とりあえず、ここまででテストが実行され、正常に終了するまでになった。

ローカルでapkファイルを作ってエミュレータで動作確認する。

テストが通ってもクラスパスがどうとかで実行時にこけるのがJavaなのでエミュレータで動作確認しておく。

以下のコマンドでapk作って起動してるデバイスにインストールできる。

mvn -f jenkins_pom.xml android:apk
mvn -f jenkins_pom.xml android:deploy

ここの内容でちょびっとハマった。
ライブラリプロジェクトをmavenで設定するときの対処法

で、動作確認までできた!よーし、Jenkinsで動かしちゃうぞ!

Jenkinsの設定

プロジェクト > ConfigureからBuild のRoot POMを"jenkins_pom.xml"に設定して、とりあえずBuild nowしたらエラッた。

cause : Compilation failure
No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?

Stack trace :
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.0:compile (default-compile) on project your-app: Compilation failure
No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?

JDK入れたつもりがJRE指定されてた。参考:CentOSで「alternatives」コマンドを使用してJavaのバージョンを切り替える

リトライ。。。エラッた。って、さっきのやつをJenkinsサーバ側でやるのを忘れてた。

dex時にライブラリがかぶってIllegalArgumentException: already added:

だから、この対応方法はダメダメなんだよなー。

でも、とりあえずできた。
と、思ったらGoogleMapが表示されない。

原因はこれだった。デバッグ時のSigningの話

今度はだいじょうぶ。
やったー!

Jenkins実践入門 ?ビルド・テスト・デプロイを自動化する技術 (WEB+DB PRESS plus)

Jenkins実践入門 ?ビルド・テスト・デプロイを自動化する技術 (WEB+DB PRESS plus)