torutkのブログ

ソフトウェア・エンジニアのブログ

自動ビルド環境とHudson

継続的インテグレーション」ツールHudsonを使った最初の一歩です。新しいツールは使いはじめるのに敷居があるので、Hudsonにおける敷居を越える参考にと日記をしたためてみました。

前置き

現在のプロジェクトでは、毎週リリースを行っているのですが、有人作業のため、作業を開始してビルドエラーが発生すると、そのたびに関係者を聞きまわって調整して、という作業が入ります。

ビルドの自動化(定期化)は、当初からの出来たらいいなリストに挙げられていますが、手が回らずに後回しになったまま現在に至っています。試験作業のウェイトが増えてきた時期に、ビルド専任者が外され、ますます手が及ばなくなってしまいました。リリース作業が大事になってくるプロジェクト終盤ですが、予算的要因のためいる人間で何とかしろと・・・(大規模だ〜といいながら、ビルド担当、構成管理担当が専任化されない・・・)。

ビルドの自動化で思いつく手は、UNIX系ならcronで一定時刻に自動実行するバッチ化を行い、ビルド自動実行結果をスクリプトで加工してHTML化をしてWebから見えるようにする、と誰でも考え付くようなことですが、この手の作業は案外と手間ひまのかかるもので、なかなか実現できません。
また、シェルスクリプト、cron、HTMLから教えなければならないというのがU30な自称「ソフトウェアエンジニア」の平均レベルらしく、やれーと言ってもやれるには隔たりがあるようです。

そんなとき、Java界隈で昔から存在は知っていた「継続的なビルド」ツールのHudsonが、実は、Javaのビルドのためのものではない、cronに変わってシェルスクリプトを実行する機能がある、ということを知りました。これならば、C++のプロジェクトも問題なくビルドできそうです。

ということで、唐突にHudsonを動かしてみました。

まずはHudsonのインストール

「インストール作業」と身構える必要は全然ありません。Hudsonについては、「考えるな、感じろ」です。頭を使う前にまず動かしてみてから、いろいろ調べるなり考えるのです。僕はどちらかというと事前に下調べをしたり仕組みを調べてからでないと新しい技術を使っていけないタイプなので、「考えるな、感じろ」というやり方は少しストレスがありますが、Hudsonについてはこれが早道です。

まず、Hudsonのプロジェクトサイト(以下URL)にアクセスし、Download(latest and great)をクリックします。ブラウザがhudson.warを保存するか聞いてきますが、「どこでもいい、とにかく保存しろ」です。「.warとはいったい何者?」とか「バージョンはいくつなんだ?」と躊躇して、キャンセルボタンを押して保存をやめてはいけません。
https://hudson.dev.java.net/

さっさと実行しましょう

インストールは完了です。えっ?、インストールはどうなったんだ? などと考えてはいけません。warファイルとは何? JavaEEとは? デプロイとは? アプリケーションサーバは?と思ってしまうと、ゆうに一週間はHudsonからあさっての方向に旅たってしまいます。

そう、Hudsonのインストールは、hudson.warファイルをマシンに保存した時点で終わっているのです。いつでも実行可能状態です。さあ、実行しましょう。以下のコマンドを入れてください。

$ java -jar hudson.war

あとは、ブラウザからhttp://localhost:8080 にアクセスします。これで実行は終わりです。あとは、実行したいコマンドをブラウザから設定します。warファイルをjarで実行?などと考えてはいけません。すばらしいことに、内蔵のWebサーバが動いているのです。後日正式運用するときに、必要であればアプリケーションサーバに配備すればよいのです。

設定

さて、設定方法はどうやるのか調べないと・・・、とGoogleやらを探し回ってしまうと、またHudsonから明後日の方向に飛んでいってしまいます。Hudsonの画面(ブラウザ上)は、各設定項目の右脇に'?'のアイコンがあり、そこに説明があります。とにかく使って分からないときは'?'を押してみる、という形でなれていくのがよいでしょう。

最初の一歩

ビルドプロジェクトを1つ作成します。まず最初の一歩なので、実験で作った小さなC++プログラムを指定して作ります。

設定項目 設定内容
プロジェクト名 始めまして、Mr.Hudson
説明 C++のテストアプリケーションをビルドします。C++のビルド環境は、MPCを使ってGNUmake用Makefileを生成した後、GNUmakeです。
ビルド手順の追加 シェルの実行
シェルスクリプト 後述

シェルスクリプト欄には以下を記述しました。

cd /home/torutk/work/cxx/sqlite/hello
mwc.pl -type make
make realclean
make

シェルの実行時、カレントディレクトリはHudsonを実行したディレクトリになるようなので、ここでは絶対パスで指定します。
mwc.plは、ACE+TAOのビルドで使われている、各種ビルドツール用の設定ファイルを生成するツールで、ここではGNU make用Makefileを生成するのに使っています。
make でクリーンビルドをしています。

これ以外の設定はデフォルトのまま(未指定)です。ソースコード管理システムとの連携はなし、ビルド・トリガもなしです。

最初の一歩はここからはじめます。

ビルドする対象がないよー

と言う方も、任意のディレクトリにHello Worldプログラムを作成し、Makefileを記述して、それをHudsonから実行するようにシェルスクリプトを記述すれば、3分間でビルドが実施できます。

Hudsonによる初ビルド

作成した「始めまして、Mr.Hudson」プロジェクトを選択し、左側メニューの「ビルド実行」を選択するとビルドが開始されます。

これでOKです。ビルド履歴欄に新しいビルドが追加されます。成功したときは、ビルド履歴欄に青い玉のアイコン付きで表示されます。

ビルド失敗時の挙動を見る

ビルドが成功すると、表示上青玉アイコンのみでつまらないので、ソースコードをいじってエラーを出すようにしてさらにビルドを実行してみました。

今度はビルド履歴に赤玉のアイコン付きで表示されました。

ビルドの実行は、RSSフィードで配信されるので、これをリーダーに設定しておくとよいようです。

Hudson初日メモ

  • プロジェクト設定のデータはどこに?

設定したデータは、Hudsonを実行したユーザ・アカウントのホームディレクトリに、$HOME/.hudsonというディレクトリが生成され、その中に作られていました。

  • ビルドが失敗したけど、エラー内容はどこを見れば?

ビルド履歴をクリックすると、左側メニューに「コンソール出力」が表われるので、これをクリックします。

  • ビルド結果のログはどこに?
$HOME/.hudson/jobs/初めまして、Mr.Hudson/builds/2009-08-23_16-20-03/log

のように、ホームディレクトリ下の.hudsonの中にjobs/<プロジェクト名>/builds/<ビルド実行年月日時分秒>
ディレクトリにlogというファイル名で吐かれます。また、buildsディレクトリの下は、ビルド番号のシンボリックリンクファイルが対応するビルド実行年月日時分秒ディレクトリにリンクするように作られています。

  • Hudsonのバージョンって?

Hudsonを起動して、ブラウザからアクセスするとページの右下にバージョン番号が表示されています。

  • ポート番号をデフォルトの8080以外にするには?

起動時に、--helpオプションを指定して調べます。

$ java -jar hudson.war --help
Running from: /home/torutk/work/hudson/hudson.war
Hudson Continuous Integration Engine ?
Usage: java -jar hudson.war [--option=value] [--option=value]

Options:
  :(中略)
   --httpPort               = set the http listening port. -1 to disable, Default is 8080

これを見て、書式(Usage)にある様式で指定します。

$ java -jar hudson.war --httpPort=8087

参考URL

Hudson開発者である川口耕介さん自身の記事です。

感想

UNIX系OSを知っていても、cronとスクリプトで頑張るのは手間がかかります。それに対してHudsonは、とりえあえずあっという間に作り上げられます。うーん、今までJavaのビルド専用かと思っていたのですが、ぜんぜんそんなことはなく、C++のビルド環境でも簡単に実現できました。最初の一歩としては上々です。

あとは、Subversionからチェックアウトしたり、定時ビルドを実行できるようにしたりと、追加していけばよいようです。また、インストールがとっても簡単なので、空いているマシンにどんどん仕掛けられます。

ビルド実行結果は、Emailによる通知かRSSフィードになってしまいますが、IRCTwitter等へ通知するプラグインがある模様です。まあ、閉じた環境での開発では、せいぜいRSSですかねぇ。