Continuous Integrationの12の勘所

個人的にCIは大好きで、いろんなところで首をつっこんでは、仕組みを学んで来ました。その勘所をかりかり書いてみました。内容が固いので文体も固いですが、この記事書いている人はこんなに固くないです。むしろゆるゆるです。

  • 最初で全ての環境(ビルド・テスト・CIサーバーの設定)を整えられればパーフェクトだけれども、一度に全部やりきるのはきっと現実的ではない。開発環境としてフルスタック揃ったものはいくつもでているけれども、プロジェクトごとに違う設定は必ずどこかにあるからだ。例えば開発用のDBは各マシンに用意しているけれども、インテグレーション用のDBは別途用意している、とか。設定は「こうすれば良くなるかも」という継続的な改善をしていくつもりで、一番最初は軽めに1時間くらいでできる範囲で一本通す。
  • 小さく産んで、環境を壊さない程度の改善を少しずつ加えて育てていく。育てられるのは製品コードやテストコードだけではない。
  • ビルドを甘く見てはならない。ソフトウェアのリリースには配布用のパッケージを作ることになると思うが、ローカルの環境をそのまま配布用に手作業でパッケージするのは、絶対にいつか手順を間違えて迷惑をかける。
  • CI環境は簡単に移行できるような設定に考えぬいておくこと。いつビルドサーバーが壊れてしまうかわからない。だからあなたのローカルで動作確認できるようにしておくのが本当は望ましい。いざとなればあなたのマシンをビルドサーバーに仕立て上げることができる。
  • ビルド用のスクリプトの中にDBのスキーマを合わせたり、テストデータのセットアップをするための処理があると喜ばれる。(これってRailsだと標準でついてるんだっけ?Rails弱者の自分は良く知りません。ゴメンナサイ。)
  • CI環境やビルドスクリプトなどに改善を加えた場合はどういうところに手を加えたか、他のメンバーに伝えること。また、ログを残すことを心がけること。プロジェクトの中でCIの面倒を見られるメンバーを増やしたいのであればなおさら。ツールを導入すればみんな使ってくれるからトラックナンバーを増やせる、という事はきっとない。面倒を見ているのはプロジェクトの中できっと数人(場合によってはあなた一人)だろう。
  • いい改善は外部に公開するとみんな幸せになれる。ビルドのコードは製品コードの一部に含まないことが多いのではないだろうか。という事は著作権は自分達にある。(プロジェクトによってはそうではない場合もあるので、そこは要確認)
  • コミット時に行うインテグレーションと、一日に一度行うインテグレーションは違う設定できるようにするといい。コミットは一日に頻発するプロジェクトがほとんどだと思うが、一回のインテグレーションに1時間とかかかってたらどんどんビルドのリクエストがキューに貯まっていってしまう。例えば時間のかかりがちな自動化された受入テストの実行は一日に一度だけ、とかにする。
  • コミット時に行うインテグレーションはコンパイルのみでもコミットした人以外にとって非常に有用だ。なぜならコミットした人は自分の変更が他の人の開発環境を壊すことに気づけないからだ。これは開発を止めてしまうので非常にヤヴァイ。
  • コミット時に行うインテグレーションはできるだけ早く結果を受け取れるようなバランスにしておくこと。コンパイルエラーが発生するような変更に気づけるのが1時間後とかだと他の人がリポジトリから変更を取得してしまう確率が高くなってしまう。
  • インテグレーションの終了時に音が鳴るのはいいプラクティス。成功時にファンファーレがなるのはチームにとってうれしい事。XFDがあるともっと喜ばれるかもしれない。
  • インテグレーションが知らせる異常に対しての作業の優先度は高めに設定しておくこと。「受入テストが通らないから後でまとめて原因を調査しよう」というように異常を放置し続けていると、何のためのCIかわからない。

いじょ。CIというより、ビルドにツッコミ気味な気もしないでもないですが、勢いで書いてみました。つっこみ、ご意見お待ちしてます。

Continuous Integrationって人間に置き換えると定期的に検診すること

CI(Continuous Integration)の価値ってなかなか伝わらないよね、だからなかなか工数削ってやろうという話にならないね、と先日リーダーと話になりました。で、不調の僕が改めて思ったことをつらつらと。で、思ったのがタイトルの通り。
人は定期的に検診を受ける事を義務付けられています。小さいころはそれこそ母子手帳に生まれる前からの記録もつけられつつ、学生時代は日々の成長を記録しつつ(『柱のきずは おととしの〜』なんてのもありますね。)、大人になったらなったで、定期健診を受けるようになっていると思います。人間ドック(にはまだ行ったことないですが。)は二日かけて体中を検診しますよね。こんな感じで生きていれば何らかの検診を定期的に受けるようになっているんじゃないでしょうか。体調に現れていない不調でも、すぐに見つけられることができれば治療しやすい、または対処しやすいからだと思います。
ソフトウェアは開発を続けていれば常に変化します。いい面では機能的な成長が達成されますが、悪い面では人よりも激しく不調を起こしながら変化します。ソフトウェアの変化は人間に比べたら遥かに速い。(そりゃ人間が何人もかかって作ってるんだから。←これもつっこまれそうですがそのまま残しておく)だから常に状態を監視できるようにしておく必要があるのではないでしょうか。そのためのCIです。
たぶん検診→CIのメタファの話はどこかに既に出典があると思ったんですが、ちょっと見つけられませんでした。ご存知の方教えてください。

Hudsonに一目惚れ

CIをするための環境を調査。昔はCruiseControlとか、Continuousとか使っていましたが、かねがね噂を聞いていたHudsonを動かしてみた。今日TracHudsonPluginを見て動かそうと思ったんですけれども。これすごいですね。何がすごいって

  • ダウンロードしなくてもJava Web Startを使ってちょちょっと試せちゃう。
  • ダウンロードしてもこんなコマンド一個で動く
java -jar hudson.war
  • ちょっと試すだけだったらAPを立てずにすむ。
  • ブラウザからほとんど全ての操作ができてしまう。
  • 特にバッチとかも不要
  • crontab互換の記法を使って定時バッチを動かす事ができる
  • master/slave機能もついている
  • Tracとの統合(他にもあります)
  • プロジェクト名/buildとかで、指定しているビルドスクリプトを実行できる

特にwarなのに-jar指定で動かそうっていう発想は僕にはなかったです。良く考えてみたらJava Web StartEclipseもいけるんじゃないかと思ったけれども、100MB単位のサイズのアプリケーションだとダウンロードがつらそうです。