けんごのお屋敷

2012-10-04

RailsプロジェクトでJenkinsを使ってCIしてみる

会社のプロジェクトでRuby on Railsを使っていて、Jenkinsを使ってCI環境を整えたくって ずっと試行錯誤していたのですが、最近ようやく出来上がったのでその全貌を明らかにします!

ちなみに全部Linuxでの話なので、Windowsの人は残念ながら役に立ちません…

目標

今回Jenkinsを使って以下のようなことがやりたかった。

  1. githubにあるリポジトリのRSpecのテストを自動的に実行したい
  2. Capybaraを使ったテストもやってるので、ブラウザが起動する環境で自動テストを実行したい。 これは別途デスクトップ環境(今回の場合はUbuntuデスクトップ)を準備してそこでテストさせたい。
  3. コードカバレッジを出力してるのでJenkinsから見れるようにしたい
  4. テストケース一覧もJenkinsから見れるようにしたい

この目標に向かっていろいろと設定をしていきます。

Javaのインストール

Jenkinsを動作させるにはJavaが必要ですのでJDKをインストールします。 この記事執筆時点ではこちらから 最新のJDKがダウンロードできます。JDKのダウンロードボタンをクリックして Accept License Agreement の ラジオボタンにチェックを入れてからLinux用のJDKをダウンロードしてインストールします。

$ cd /usr/local/src
$ wget http://download.oracle.com/otn-pub/java/jdk/7u7-b10/jdk-7u7-linux-x64.rpm
$ rpm -ivh jdk-7u7-linux-x64.rpm

これでインストール完了。

$ java -version

と打って、Javaのバージョン番号が表示されれば成功。

Jenkinsのインストール

yumで簡単にインストールできます。以下rootユーザーで作業します。

$ wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
$ rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
$ yum install jenkins

これだけです。そして以下のコマンドで起動できます。

$ /etc/init.d/jenkins start

この状態でhttp://hostname:8080/にアクセスするとJenkinsの画面が開きます。

JenkinsDashBoard

プラグインのインストール

Jenkinsには豊富なプラグインが存在します。 今回の目標としていることも、プラグインなしには実現出来ないので、まず最初にプラグインをインストールします。 Jenkinsの管理プラグインの管理 とたどっていき、 利用可能 のタブをクリックします。 今回使うプラグインは以下の3つです。

  • Jenkins GIT plugin Jenkinsからgitを扱えるようになります。
  • Jenkins Rake plugin JenkinsからRakeタスクを実行できるようになります。
  • Jenkins ruby metrics plugin Rcov形式のテストカバレッジのレポートをJenkins上で表示できるようになります。

JenkinsDashBoard

プラグインは大量にあって見つけるのが大変なので、フィルターにプラグイン名の一部などを入力して検索します。 プラグインが見つかったらチェックボックスをつけて画面下側にあるボタンをクリックしてインストールします。 再起動せずにインストール の方が再起動しないので、時間もかからず簡単そうです。

JenkinsDashBoard

スレーブサーバーの用意

Capybaraのテストをブラウザを使って実行するためのUbuntuデスクトップ環境を別途準備します。 (別にUbuntuデスクトップをマスターにしてもいいんですが、今回スレーブを試してみたかったので…)

各種インストール

スレーブサーバーにはマスターと同じようにJavaやJenkinsをインストールします。 Jenkinsはインストールするだけで起動はしなくても良いです。 また、ここでテストを実行することになるのでgitやrubyもインストールしておきます。

鍵の登録

このサーバーでgithubからcloneすることになるので、githubにJenkins実行ユーザーの鍵を登録しておきます。 yumでJenkinsをインストールした時に自動的にjenkinsというユーザーができていて、そいつがJenkinsの実行ユーザーなっています。 ただ、jenkinsというユーザーにはログインシェルがなくてログインすらできずに、鍵を作れなかったのでとりあえずログインシェルを登録して鍵を生成。

$ usermod -s /bin/bash jenkins # rootユーザーで。とりあえずbashを設定
$ su - jenkins
$ ssh-keygen -t rsa # パスフレーズは空で。Enterキー連打で鍵生成
$ cat ~/.ssh/id_rsa.pub

id_rsa.pubの内容をgithubに登録します。鍵の登録はgithubにアクセスして、 (画面右上の)Account Settings > SSH Keys > Add SSH key からできます。念のため登録がうまくいってるかどうか確認。

$ ssh git@github.com
$ Hi tkengo! Youve successfully authenticated, but Github does not provide shell access.

Jenkins(マスター側)の設定

さて、ここからJenkinsの設定をしていきます。 最初はどこに何を指定していいのかが全然わからないんですよね、これ…

プロジェクトの新規作成

新規ジョブ作成 から フリースタイル・プロジェクトのビルド を選択。 ジョブ名 は適当に自分がわかる名前をいれればよいです。 CreateNewJob

スレーブの登録

先に作ったUbuntuのデスクトップを、マスターのJenkinsにスレーブとして登録します。 Jenkinsの管理 > ノードの登録 > 新規ノード作成 とたどっていきます。

RegisterSlave

こんな感じに設定します。 ホスト のところは自分の環境のホスト名に置き換えてください。

鍵の登録

スレーブを設定した時、起動方法に SSH経由でUnixマシンのスレーブエージェントを起動 を選択しているので、 スレーブのjenkinsユーザーにマスターのjenkinsユーザーの鍵を登録します。 スレーブサーバーで鍵を作ったのと同じ要領でコマンドを実行します。 鍵ができたら、それをスレーブサーバーに転送して登録します。 コマンドラインでやるとするとこんな感じ。

$ # マスターサーバーのjenkinsユーザーにログインしてやる
$ # スレーブサーバー名は適宜自分の環境の名前に置き換えて下さい
$ scp ~/.ssh/id_rsa.pub jenkins@jenkins.ubuntu.local:/home/jenkins
$ ssh jenkins@jenkins.ubuntu.local
$ # ここからスレーブサーバーのjenkinsユーザーでの操作
$ cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys

念のためパスワードなしでログイン出来るかどうか確認。

$ # マスターサーバーのjenkinsユーザーで
$ ssh jenkins@jenkins.ubuntu.local

SCM

githubを使うので当然gitを選択します。 リポジトリ名とブランチ名を入力するエリアが出てくるのでそれぞれ入力します。

SettingSCM

リポジトリを入力すると認証に失敗した旨のエラーメッセージが出ますが、認証のための鍵は、 実際にテストを実行するスレーブサーバー(Ubuntuデスクトップ)側で登録しているので無視します。

ビルド・トリガ

テストを走らせるためのトリガを定義します。githubにpushされたら自動的にテスト実行というのが理想的なのですが、 Jenkinsが社内ローカル環境にあるため、githubからのpush通知を受け取れません。

なので、githubを5分毎に見に行って(ポーリング)更新があればテストを走らせるようにトリガを設定しました。

SettingBuildTrigger

ビルド

いよいよここでテスト実行の設定をします。といっても、単にテストの時に手動で打ってるコマンドを実行するだけなんですが。 シェルの実行 を選んで、今回の場合はこんな感じ。

SettingExecuteShell

export DISPLAY=:0.0 の部分はUbuntuデスクトップでコマンドラインからGUIのブラウザを起動させるために必要な設定です。 GUIのプログラムを起動するためのディスプレイの番号を指定しないといけないようです。 これを指定していないとFirefoxが起動せずに、1日くらいはまりました。

ビルド後の処理

ビルドが終わった後の処理を定義していきます。 まず、今回のRailsプロジェクトではci_reporterというgemを使って、 テスト結果をJUnit互換のxml形式に吐き出しています。 それをJenkinsに食べさせてJenkinsから参照できるようにします。

SettingAfterBuild1

それと、simplecovsimplecov-rcovというgemを使ってコードカバレッジも出力しています。 これも同様にJenkinsに食べさせることで、Jenkinsから参照できるようにします。

SettingAfterBuild2

ビルド実行

さて、ようやくここまででJenkinsの設定が終わりました。どきどきしながら ビルド実行 をクリックします。

SettingExecuteBuild

VNCでUbuntuデスクトップを覗いてみると…おおおおFirefoxが起動してテストしてくれてる! 試行錯誤を繰り返した末にきちんと動いてくれたのは感動的でした。

あとはJenkinsが取り込んでくれたテスト結果やコードカバレッジのグラフなんかをみてニヤニヤします。

終わりに

どうでしたか。導入がなかなか大変だとは思いますが、環境を作ってしまえばとても楽しいです。 ここに紹介した他に、今うちのチームではビルド後の処理として、テストが終わる度にIRCチャンネルに通知するという処理をやっています。 それでこんな運用をしています。

  • プログラマがソースコードを修正してgithubにpush
  • Jenkinsが5分に一回拾ってくれて自動的にテストを走らせる
  • ディレクターやリーダーなどがIRCでその通知を確認
  • Jenkinsからgitのログを参照して、変更点を確認する

まだまだ始めたばかりで試験的ではありますが、なによりちゃんとCIされてる感じで楽しいです。

CIライフはじめてみませんか。

  • このエントリーをはてなブックマークに追加