What is it, naokirin?

JenkinsとGitとSpockで独り継続的インテグレーション

明日は大阪で楽しくXPを体験してこようと思ってます、なおきりんです。(XP一日体験ワークショップ! - http://kokucheese.com/event/index/30196/

今回、継続的インテグレーションが参加するイベントの一つにあげられているので、先取りで独り継続的インテグレーション環境を作ることにしました。

ちなみに今回使っている環境は

  • Mac OSX Lion (Mac book pro)
  • JDK6(Mac上でのJDK7は挙動がまだ怪しいのでJDK6が安定のようです。2012/03/30現在)
  • Groovy 1.8.6
  • Jenkins 1.454
  • Gradle 1.0-milestone-9
  • JUnit 4.10
  • spock-core-0.5
  • Git 1.7.7.5

となっています。蛇足ですがIDEIntelliJ IDEAです!(ココ!重要!)

Gradleでビルド

まずはGradleでビルドすることから始めます。

Gradleでのビルドでは次のようなディレクトリ階層を使います。

project_root
├── build.gradle   -> ビルド設定ファイル 
├──build               -> gradleが生成するディレクトリ
└── src                 -> ソースコードのディレクトリ
    ├── main          -> プロダクト用ディレクトリ
    │ ├── groovy   -> groovy用
    │ └── java       -> java用
    └── test            -> テスト用ディレクトリ
        ├── groovy
        └── java

今回はテストをGroovy、プロダクトをJavaで書くことを想定してみます。(おそらく別の組み合わせでも今回紹介する方法でそれほど困ることはないと思います。)

そこでまずbuild.gradleを記述します。

// build.gradle
apply plugin:'groovy'
apply plugin:'application'
apply plugin:'maven'
apply plugin:'java'

def defaultEncoding = 'UTF-8'

// Macでjdk7では:testが失敗するのでjdk6で実行
//def jdkVersion = 1.7
//sourceCompatibility = jdkVersion
//targetCompatibility = jdkVersion

[compileJava, compileTestJava].each{ it.options.encoding = defaultEncoding }

repositories {
    mavenCentral()
}

dependencies {
    groovy group:'org.codehaus.groovy', name:'groovy-all', version:'1.8.6'
    compile 'asm:asm:3.2'
    testCompile group:'org.spockframework', name:'spock-core', version:'0.5-groovy-1.8'

    // optional dependencies for using Spock
    testCompile "org.hamcrest:hamcrest-core:1.2"
    testRuntime "cglib:cglib-nodep:2.2"
    testRuntime "org.objenesis:objenesis:1.2"
}

// Executable Jar
jar {
    from configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}

build.gradleはいろんな人のを参考にしたつぎはぎに近いです。必要に応じて書き換えていってください。

そして、src.main.java下にプロダクト用のJavaソースコード、src.test.groovy下にテスト用のSpockによるテストコードを配置してプロジェクトのルートで

gradle test

を実行するとテストが走ります。

Gradleでカバレッジ(Cobertura)

これに関しては次の記事が非常に有用でした。

Gradle でカバレッジを計測してみる その2 - http://d.hatena.ne.jp/bluepapa32/20110618/1308365533
(Gistはこっちのようです。https://gist.github.com/1030834

この記事の通りでほぼいいのですが、cobertura.gradleの32行目にある

fileset(dir: sourceSets.main.classesDir)

の部分を

fileset(dir: sourceSets.main.output.classesDir)

にしないと私の環境では期待通りに動きませんでした。

Gitでバージョン管理する

Jenkinsを動かす前にGitで先ほどのディレクトリをバージョン管理しましょう。

Gitの使い方に関しては、Web上のいろんな情報や本の方に任せるとします。

ですが今回問題としてあがるのが、「GradleでCoberturaを動かすときにmain.groovyやtest.javaといったディレクトリが必要なのに、Gitでは空のディレクトリは管理されない」ということです。
これに関しては.gitkeepというファイルを管理したい空のディレクトリに入れることで解決できます。

Jenkinsで回す

いよいよJenkinsで回す準備ができたので、回しましょう。

まずプロジェクトを作成する前に、必要となるプラグインを入れていきましょう。
今回必要なプラグインは次のものです。

  • Jenkins Cobertura Plugin
  • Jenkins Git Plugin
  • Jenkins Growl Plugin(任意)

これらを Jenkinsの管理=>プラグインの管理 よりインストールしてJenkinsを再起動してください。


次にJenkinsで「新規ジョブ作成」をして、「フリースタイル・プロジェクトのビルド」を選んでプロジェクトを作成します。
作ったプロジェクトの「設定」を行いましょう。

  • 今回はテストのみの実行を考えるため、「ビルド」は「シェルコマンドの実行」を選び、「シェルスクリプト」のところは「gradle test」にする。(Windowsの場合は「Windowsバッチコマンドの実行」を選ぶ。)
  • 「Cobertura カバレッジ・レポートの集計」にチェックを入れ、「Cobertura XML レポート パターン」に「build/reports/cobertura/*.xml」を指定する。
  • JUnitテスト結果の集計」にチェックを入れ、「テスト結果XML」には「build/test-results/*.xml」を指定する。
  • Growlにて通知してほしい人は「Growl」にチェックを入れ、IP アドレスを指定する。(ローカルなら「127.0.0.1」ですよね)

上記の設定を行い、ビルドを実行してみましょう。
問題がなければ、ビルド履歴に青い丸の#1ができ、プロジェクトにテスト結果やカバレッジレポートが追加されるはずです。

もっと自動化!

さて、どうせならGitにコミットしたタイミングでJenkinsさんに働いて(ビルド実行して)もらいたいところです。

そんな時にはリポジトリにある.git/hooks ディレクトリ下に「post-commit」という名前の以下のような内容のファイルを作りましょう。(<project-name>は適宜自分のJenkins上のプロジェクト名に変更してください。)

#!/bin/sh
wget --no-proxy --spider http://localhost:8080/job/<project-name>/build?delay=5sec || echo "jenkins job-kick failed"

その後、実行可能ファイルにするために

chmod u+x post-commit

を実行してください。

これにより、コミット後にJenkinsの指定のプロジェクトのジョブ(今回はテスト)を実行するようになります。
Growlがあれば、Growlによりテスト成功・失敗の通知もされます。便利ですね!


追記(2012/04/02)
XP一日体験ワークショップに行ってきたので、ついでに受け入れテスト環境を作ろうと思ったのですが、ちょっと挫折。

うーん、受け入れテスト環境って作ったことなかったのでいきなりは無理でした(というよりほかの自前リポジトリに依存するとかやったことなかったw)。

ですが、Jenkins側でジョブ自体の管理としてちょっとしたいいものをみつけたのでちょっと先に行くための解説として追加することにしました。

ビルド・パイプラインを視覚化!

今までの説明は独り用特化だったので結合テストや受け入れテスト、デプロイのフェーズがありませんでしたが、その部分にちょっと踏み込んでJenkinsをより使いやすくしちゃいましょう。

そこでJenkins上のとあるジョブの後にジョブを実行するといった機能がJenkinsにはあります。
ジョブで「設定」に次のように「ビルド・トリガ」の設定でできます。

しかしながら、これだけでは結合テスト・受け入れテスト・デプロイ等々連なっていくとそのビルドパイプラインが追いづらくなります。
そこでプラグインである「Build Pipeline Plugin」を使って、視覚的にビルドパイプラインを見れるようにしましょう。

まずはJenkinsに「Build Pipeline Plugin」をいれます。

次にJenkinsのトップにプロジェクト一覧が並んでいる上に「+」の部分があると思いますのでそれをクリックします。
すると「Build Pipeline View」というチェックがあるのでそれをチェックしてビルドパイプラインのビューを作ります。

次にビューのタイトル、そのビルドパイプラインの最上流となる(つまり最初に走る)ジョブを設定します。
あとは過去のビルドの成功・失敗を何個まで表示するか指定してあげればOKです。

すると、トップページの「すべて」や「+」があったタブにビューのタブもできているはずです。それを選択すると次のようなビルドパイプラインの表示が出るはずです。

ビルドパイプラインを管理するときは便利!