Jenkins CIでRSpecを自動実行する
今回は「Jenkins CI」のお話
きっかけはGunma.web #4でのLTでした
Gunma.web #4 (on 2011/02/12) まとめ - ぱろっと・すたじお
Jenkins CI(旧Hudson)の話を最初に聞いたのはデブサミ2009?だったと思いますが、
本気で使おうと思ったのはこのLTを聞いて、いくつか質問したときです
(RakeやGitでも使える、的な話)
あと、WEB+DB PRESSでも(テスト関連ツールとして)紹介されていました
- 作者: 西岡祐弥,濱田章吾,浦嶌啓太,高橋健一,柴田博志,井上誠一郎,大谷弘喜,荻野淳也,原悠,増井俊之,横山彰子,浜本階生,ミック,uupaa,塙与志夫,はまちや2,大沢和宏,中島聡,矢野りん,中島拓,角田直行,WEB+DB PRESS編集部
- 出版社/メーカー: 技術評論社
- 発売日: 2011/02/24
- メディア: 大型本
- 購入: 37人 クリック: 2,058回
- この商品を含むブログ (38件) を見る
このVol.61はRails3のテスト手法だけで十分価値があるにもかかわらず、
先日のデブサミ2011で紹介されていた「Titanium」の話や、
話題のScala/Clojureの話まで載ってるので、ぜひ買ってください(`・ω・´)
で、Jenkinsは要するに「自動で何かをしておいてくれる」ツールでして、
今回は「commitしたらテスト」とか「定時テスト」を自動でやってもらい、
ダメだったらメールで通知をもらう・・・という環境を作りました
構築手順そのものは何も難しいことはないので、
後半に「何につまずいたか」をメモしておきます...φ(・ω・`)
環境
構築
基本はwarファイルをダウンロードしてきて実行すればいいのですが、
RHEL/CentOS向けにrpmファイルが用意されてますので、
そちらを使うのが簡単です
http://pkg.jenkins-ci.org/redhat/
サイトではyumを使った方法が紹介されていますが、
rpmで導入した場合も /etc/yum.repos.d/jenkins.repo が作られます
ただ、これだとyum実行時に毎回Jenkinsのリポジトリを見にいくことになるため、
それが気に入らない場合は「enable=0」を追加しておいて、
yum実行時に「--enablerepo=jenkins」とした方がいいかもしれません
次に、「/etc/sysconfig/jenkins」にある設定ファイルをいじります
とはいえ、せいぜい変えるのは「JENKINS_PORT」くらいではないかと
「8080」を使ってなければ何も変えなくてOKです
後は起動するだけです
お好みで自動起動の登録も
# service jenkins start # chkconfig jenkins on
以降は全てブラウザで操作できます
「http://サーバ名:設定ポート」にアクセスすると、
メイン画面が表示されます
まずやることはプラグインの導入です
「Jenkinsの管理 -> プラグインの管理 -> 利用可能」とたどると、
ずらっとプラグイン一覧が出てきますΣ(゚Д゚;≡;゚д゚)
「GitでpushしたコードをRakeで実行する」のが目的なので、
以下のプラグインを入れました
- git plugin
- rake plugin
- ruby plugin
インストールと再起動が終わったら、
「Jenkinsの管理 -> 設定」からGitやRuby、メールの設定を行います
驚いたのが、Ruby/RakeプラグインがRVM*1に対応していることですΣ(・ω・ノ)ノ
RVMの管理PATHを渡すとたぶんRubyを自動で認識してくれそうな予感
今回のサーバはRVMを入れてないし、入れる気もないので、
RubyのインストールPATHをそのまま設定しました
あと、Gitが特殊なPATHに入っている場合、
GitのPATHも設定が必要かもしれません
実行するjenkinsユーザでgitが実行できればOKです
ジョブの設定
これでJenkinsを使う準備ができたので、
今度は「新規ジョブの作成」を行います
いろいろなタイプがあるようですが、
今回の場合は「フリースタイル・プロジェクトのビルド」でOKです
ここでつけた名前がジョブの格納PATHに使われます
(/var/lib/jenkins/jobs/ジョブ名)
後は「何をやってもらうか」を設定していくわけですが、
私が設定したのは以下の項目です
ソースコード管理システム
今回の場合は迷うことなく「Git」を指定します
「URL of repository」にリポジトリの場所(HTTP/HTTPS/Local)を指定します
SSHでアクセスしている場合、jenkinsユーザでアクセスできないとダメです
私はこのパターンに引っかかったので、
開発環境からローカルのリポジトリにpushすることに(後述)
ビルド・トリガ
cronのような書式で、「いつジョブを起動するのか?」を指定します
私が設定したのは以下の二つ
- SCMをポーリング -> */5 10-19 * * 1-5
- 平日の10時から19時の間、5分おきにリポジトリをチェック
- 定期的に実行 -> 15 8 * * 1-5
- 平日の朝8:15に実行
前者は「新しいcommitがあったら実行」で、
後者は「定時に強制実行」ということです
ビルド
ビルドとは「実行の主体」のことです
今回の場合でいえば「Rakeでspecを実行する」ということになります
cd $WORKSPACE;/usr/bin/rake jenkins:spec
「$WORKSPACE」は実行時に「/var/lib/jenkins/jobs/ジョブ名/workspace」に変換されます
「jenkins:spec」は「spec:all」とやってることは同じですが、
Jenkinsの環境に合わせたhelperをrequireするようにしてます(後述)
ビルド後の処理
実行が終わったら何をするか、です
実行の成功・失敗はブラウザで確認できますが、
「E-mail通知」を設定しておけば、エラー時にメールが飛んできます
他にもいろいろ処理がありますので、
実際に確認してみてください
実行
最後に、「ビルド実行」を選んで一度動作させてみてください
結果はログや「コンソール出力」から確認できます
Rake実行の結果、青いランプが点灯したら、
後は放置するだけです
commit -> pushしてspecが通らなければメールが来ます
個人的に詰まったポイント
・・・とまあ、手順だけ書くとわりと簡単なんですが、
実際にはかなり手間取りました(´-ω-)
せっかくなので、その内容をメモしておきます
特に興味がなければスルーしてください
Ruby1.9.2のインストール失敗
現在メインサーバとテストサーバがあるのですが、
リポジトリはメインサーバにあります
なので、メインサーバでJenkinsを使えばいいのですが、
メインサーバは1.8.7/Rails2で動いているため、
1.9.2/Rails3で動く開発中のシステムは動作しません
設定にRVMがあるくらいなので、それでやろうと思ったら、
なぜか「rvm install 1.9.2」したときmakeでこけるのですΣ(・ω・ノ)ノ
しかも、ソースをダウンロードしてmakeしても同じ場所で落ちるので、
どうもメインサーバの何かが壊れてるんだと思いますが、
無茶なupgradeを繰り返した関係でこれ以上いじりたくないのです
結局、最初からRuby1.9.2/Rails3で動いているテストサーバを使いました
Gitリポジトリ環境
ということで、テストサーバがメインサーバのリポジトリにアクセスすればいいんですが、
SSH接続しか構築してない上、SSH接続に鍵を使っています
となると、jenkinsユーザ向けにSSH鍵環境を作らなければならず、
いろいろ問題が出そうなので、テストサーバにもリポジトリを作り、
開発機からそちらにpushする作業フローにしました
最初は「2カ所にpushとか面倒・・・(´-ω-)」と思ったのですが、
「Jenkinsでspec実行して通ったものだけメインにpush」と考えると、
わりと合理的な気もしてきます
specの環境依存
一番時間がかかったのが、Jenkinsとまるで関係ないspecの問題です
今やっているいくつかのシステムのうち、
Railsに依存しないAPIのコードをJenkinsに適用してみたのですが、
これがJenkins環境で全く動きませんΣ(゚Д゚)ガーン
そもそも、このAPIのspecはRSpecを覚えたばかりの頃に書いたので、
「specを書いて通すこと」が目的になっている上、
環境に依存しまくりで、開発機でしか通らないコードになっていたのです
それこそ、RDGCのspecはspecそのものは汚いですが、
「どこでも実行可能」という点で圧倒的に優れています
複数の人で開発していればもうちょっと考えたと思うのですが・・・
ということで、落ちた箇所を片っ端から外に切り出し、
ひたすらspecのリファクタリングを行った結果
「一応」通るように修正できましたが、丸一日かかりました(´・ω・`)
specの思想的にまずい記述も多々あるのですが、
さすがに一から書き直すには膨大すぎましたし、
一応とはいえ正常に動作しているコードですからね・・・
さすがに後から始めたRails3側のspecはそれよりましですし、
さっきのRails3テスト手法を参考に、
わりと綺麗なspecが書けているので、こっちはすぐ構築できるかと
(このあたりの話はまた機会があれば・・・)
というわけで、今回は「Jenkins CI」を構築した話でしたが、
自動実行する仕組みはJenkinsに限らずいろいろあります
ただ、Jenkinsは開発言語等に依存しないことや、
豊富なプラグインによっていろいろできるという点で、
実に汎用的な仕組みだと思います
特に、テストの数が多くなるほど、
部分的なテストで済ませて全体のテストを忘れがちになるので、
代わりに自動でやってくれるというのはかなり便利です
「自動で時間がかかる何かをしたい」というときにはたいてい使えると思いますので、
ぜひ一度試してみてくださいね(`・ω・´)ノ
*1:良ければ前に私が書いた記事を(´・ω・)っ http://d.hatena.ne.jp/parrot_studio/20110117/1295253527