Posts Tagged ‘Hudson’

Subversion, Git, Redmine, Hudson – 結局こうなった

3月 21st, 2010


前に考えていた開発プロセスの変更を色々試行錯誤してみてある程度固まってきました。過去の記事は以下からどうぞ。

ネットワークが切り離された外部チームとのやりとりは結局git bundleにしました。外部チームからはパッチでもらい、レビューした後に適用する。ある程度開発が進んだらgit bundleでリポジトリをコピーして外部チームに送付。外部チームはbundleファイルをそれぞれcloneして開発を行い、適宜git fetch/git pullしながら更新に追従します。タスクの粒度が1タスク1人だったこと、外部チームで別途central repositoryを設けることによるメリットが読めなかったのでこの形を取りました。開発メンバのGitレベルが上がればまたちがった使い方があるのかもしれません。チームの大半が入門Gitを読んだ程度だとこれぐらいから始めるのが混乱が少ないようです。
「masterだけ送ればいいから % git bundle create reponame.bundle master」でOKと思ってbundleファイルを作ったところclone出来ない問題が起きて半日ほどハマることがありました。「% git bundle create reponame.bundle master HEAD」じゃないと駄目みたいです。リポジトリ全部のコピーを送るなら「% git bundle create reponame.bundle –all」でもいけます。

以前はgitリポジトリの変更をSubversionに自動で書き戻すことを考えていましたが、GitとSubversionを共存させる » tune webで書いたようにSubversionに登録されたソースが削除されてしまうことがあり、結局手動にしました。週に1回ぐらい書き戻すことを想定しています。それに合わせてRedmineやHudsonが参照するリポジトリもgitに変更しました。

Hudsonのgitプラグインでポーリングする設定をしてみたのですが、ポーリングのログを書き込むところでたまにエラーが起きて止まってしまうため、gitのフックスクリプト(post-receive)でHudsonのジョブをcurlでキックするようにしました。ジョブはWindowsとLinuxとあるのですが、Windowsが苦戦しました。まずWindowsのジョブを実行するPCにmsysGitを入れて、コマンドプロンプトからgitコマンドが叩けるようにします。次にHudsonのgitプラグインでは認証を入力することが出来ないので、gitリポジトリをhttpで読めるようWebサーバの設定を行いました。gitのhttp公開は単にリポジトリのフォルダにアクセス出来るようすれば良いだけなので簡単です。あとはhooks/post-updateに”git update-server-info”を追加すればOKです(参考:git update-server-info)。

Hudsonのgitプラグインはテスト対象をワイルドカードを含むブランチ名で指定できるので、少し時間をかければpre-test commitも出来そうです。前は良く分からないなんて書いてしまいましたが、少しgitプラグインを使ってみれば感触がつかめるのではないかと思います。近々に必要な機能ではないので、また時間がある時に試してみようと思っています。

Redmineでgitを参照するにはRedmineと同じサーバにbareリポジトリを置く必要があります。別サーバで動かしているなら中央リポジトリからRedmine用のリポジトリに自動でpushする設定をすればいいでしょう。Redmineの昔のバージョンではリポジトリビューワが遅かったらしいのですが、0.9以降で試した限りでは気になるほどではありません。Subversionの頃よりも見やすくなった気さえします。trunkとbranchを切り替えて表示するのがSubversionより楽だと思います。リポジトリビューワがあまりに見やすいのでgit-webのインストールをやめたほどです。ソースレビューにgerritを検討しましたが、LDAP認証の設定をするところでうまく動かず断念してしまいました。最もr-labs – Code Review – Redmineが最近のバージョンアップでどんどん良くなっているので不要かもしれません。Redmineがより使われるようDoxygenで自動生成している内部仕様書もRedmineのRedmine – PluginEmbedded – Redmineですぐ見れるようにしてみました。

gitのフックスクリプトはhooks/post-receiveでメールを流す設定だけ有効にしています。コミットメッセージに Issue ID を含むことを強制させる Git のフックスクリプトを書きました|SNS構築の手嶋屋を参考にhooks/updateをつくってみたのですが、gitで自動生成されるコメント(マージとか)はRedmineのコミットIDを含まないのが問題になり結局止めています。この辺はまた時間をとってフックスクリプトを見直す必要がありそうです。

時間もかなり費やしましたが、昨年までよりも開発に専念出来る体制がようやくできました。Joel先生も分散バージョン管理で間違いないって、ベイビーと言ってるほどなので分散バージョン管理に移行しましょう!

Subversion, Git, Redmine, Hudson – 今考えている連携2

2月 27th, 2010

Subversion, Git, Redmine, Hudson – 今考えている連携 » tune webでいただいたコメント、実際にやってみて出来なかったことを反映してアップデートしてみました。

前回からの差分がいくつかあります。

  • git svnの窓口となるリポジトリとgit開発時のcentralとなるリポジトリを分けた。
  • 内部設計書としてソースからDoxygenで生成したものを使っていたことを思い出したので追記
  • 外部との作業項目のやりとりにRedmineからチケット一覧をExcelをエクスポートして使っているのを追記
  • お互いにパッチを送り合うのをやめて、パッチをもらったらgit-bundle(1)で作成したファイルを送るようにした。これなら物理的に離れていても同じリポジトリを使って作業出来る。

gitとSubversionの橋渡しにかなり悩んだのですが、実用Gitによると、窓口を1つにして、いくらか気をつけなければならない点があるそうです。これはまた別のエントリで。

上記構成が出来そうな目処はついてきたんですが、余力があればgerritOverview — Sphinx v0.6.4 documentationTestLinkをうまく組み合わせたいですね。

◯2010年3月3日追記
離れた箇所にリポジトリをコピーするのにはgit bundleは便利だけど、差分を渡し続けるのは無理がある気がしてきた。
masterを両者で同期を取るとなると、git bundleで貰う側はローカルのmasterにpushしちゃうとbundleからpullするのが面倒になる。ローカルでmasterにコミットするなというのは結構な制限を課している気がする。branchを切って、branchを同期するようにすると、branchからcherry-pickするような運用になるのだろうか? じっくり同期を取れる気がするけど、そこまでして同期をとらなきゃいけないものでは無い気がする。

そこまでしてリポジトリの同期を取るよりも、素直にパッチを送り合う方がいい気がしてきた。リポジトリ構成さえあっていれば最初のbundle送付すらいらないかも。
前にコメントをくれたmootohさんも、よくよく読んでみると「bundleを最初に送付して、あとはパッチを”送り合ってる”」てなってるし。

何か思い違いをしているかもしれません。おかしな点に気づかれた方は遠慮なくツッコミください。

Subversion, Git, Redmine, Hudson – 今考えている連携

2月 21st, 2010


これからが本番、検索エンジンから来た方は先にSubversion, Git, Redmine, Hudson – 現状の連携 » tune webを読むことをおすすめします。上記が週末考えていた「こういう連携なら今の問題点を解消できるかな」と思えるフローです。「こうしたほうがいいよ」とかコメントありましたらお待ちしています。

1番のポイントはバージョン管理システムとしてGitを中心に据えました。社内はSubversionで統一するという規則があるので残すとして、開発チーム内ではgit svnを使ってGit化し、Subversionを直接触らないようにします。協力会社はSubversion縛りが無いのでGitで統一してもらいます。これまでは差分ファイルを送り合っていましたが、Gitを使えばパッチをうまく作り、修正単位でパッチファイルをやり取りすることが出来るでしょう。これまでは複数の修正がまとめて送られてきてましたが、パッチ単位ならレビューもやりやすく、「こうした方がいい」とか「こうして欲しい」というやりとりもやりやすくなります。

リポジトリがプロジェクト専用になるので、フックスクリプトも仕掛けやすくなります。現状は「空メッセージのコミットは禁止」程度の緩めのものですが、コミットメッセージに Issue ID を含むことを強制させる Git のフックスクリプトを書きました|SNS構築の手嶋屋を参考にすればRedmineのチケットが無いコミットは禁止できます。これで闇コミットがなくなるはず。

さらにGitを使えば「歴史を書き換えて」テストが通らないコミットをなかった事にも出来るはずです。コミット前にテストをする機能がTeamCityにはありますが、Hudsonにはありません。[#HUDSON-1682] Pre-tested commit feature – Hudson JIRAとして要望が挙げられていますが実現はまだ先になるでしょう。HudsonのGit Pluginのページにpushされた変更をテストして、成功したらmaster/stableにマージする設定手順がありましたが、リリースブランチを持ったときにも同じように出来るかは不明です。

というのをtwitterにつぶやいていたところ、@bleisさんと@masanobuimaiさんから情報をもらえました。Gitのフックスクリプトですが

  1. pre-receiveでpush前の状態をタグ付けする設定を追加
  2. post-receiveでHudsonの複数ジョブをキックして起動。
    1. テスト結果を取得して全て成功したらタグを消してgit svn dcommitを実行
    2. 1つでも失敗していたらpre-receiveでタグ付けしたバージョンに戻してpushをなかった事にする。

とすることでいけそうです。Hudsonのジョブ実行結果を知る方法は複数あると@masanobuimaiさんに教えてもらったのがPlugins – hudson – Hudson Wikiのページです。プラグイン無しでもリモートAPIを使っても出来るのかもしれません。
自前でフックスクリプトを用意する必要がありますが、出来ないことはなさそうです。
post-receiveでのテストに多少の時間がかかることを踏まえ、Redmineで参照するリポジトリはGitではなくSubversionにするのが良さそうです。

あとはRedmineのメール経由のチケット登録機能を有効にして、HudsonのナイトリーテストでこけたらカスタマイズしたメールをRedmine指定のアドレスに送ればOKですね。上の絵には「静的解析とメトリクス集計」が入ってますが、これは内製ツールです。リポジトリを集中管理してもらえるとこういうこともやってもらいやすくなりますね。

上記構成に3月中に取り組む予定です。うまく行くといいんだけど。

Subversion, Git, Redmine, Hudson – 現状の連携

2月 21st, 2010


会社の仕事を「Gitを中心に据えた開発ワークフロー」に変えたいなとこの週末ぼんやりと考えていたんですが、現状を整理して残しておくのも、あとで振り返った時も参考になるかもしれないと思って残しておきます。

開発しているものは画像処理ライブラリで、言語はC言語。プラットフォームはWindowsとLinux両方に対応していて、32bitと64bitどちらでも動くようにしたいのが前提。ほとんどのソースは共用出来るようにしています。開発者はWindowsを使ってVisualStudioで開発し、自動テストやリリース時はLinuxでMakefileを使ってビルドします。

バージョン管理は課で管理しているSubversionを使い、他のプロジェクトともリポジトリを共用しています。他に使っているツールはテスト自動化にHudsonとタスク管理と障害管理でRedmineがあります。Hudsonは2種類のテストを管理していて、コミットの度に動くビルドのテストとCUnitを使った単体テストと、毎晩複数枚の画像入力を処理するストレステストの実行を制御しています。Redmineはチケット駆動開発(TiDD)を意識し、コミットはチケットに関連付けるようにしています。あとは開発者の1人(自分です)がgit svnを使ってローカル開発をgitにしているぐらいです。

開発メンバは社内に2人、あとは社外の協力会社に手伝ってもらっています。両者の間にはネットワーク的に「超えられない壁」があり、リポジトリを参照させることができません。ということで双方でSubversionリポジトリを持ち、同期は定期的(1〜2週間おき)に差分ソースを送り合って手動で実行しています。

ここまでが現状の紹介、以下は上記フローによる問題点です。
問題1 双方でのソースの同期を取るのが大変
一週間から二週間に一度差分ファイルを送り合ってるけど、マージに時間がかかる上、複数の変更がごっちゃになっておくられてくるためレビューしたくても途中で断念してしまう。

問題2 単体テストが通らないコミットが履歴に残り消せない
ちょっとしたミスがあってビルドに失敗してもsvnの履歴が消せない。Windows上での単体テストはコミット前に確認するけどLinuxで毎回やるのが面倒になったり、32bitと64bitを全組み合わせでやるのは面倒だったりする。動くだろうと思ってコミットすると壊れていたりとか。
あとはgccでは警告をエラー扱いしているので、使われてない変数があるとかその程度のことでエラー扱いされてしまう。

問題3 闇コミット
RedmineでTiDDに近いことをしているが、闇コミットが結構ある。スタイル直しただけとか、変数名リファクタリングしたとか。複数プロジェクトでリポジトリを共用してるからチケットIDが無いコミットを弾くのが難しい

問題4 Redmine上でチケットとコミットの関連付けを直せない
テストで問題が見つかってもRedmineのチケットとコミットの関係を直すことが出来ない。間違ってるfixesが残ってしまい、何とも出来ない

問題5 HudsonでビルドにコケてもRedmineのチケットに自動登録されない
Hudsonでコミットごとの単体テストとは別にストレステストを含むナイトリーテストを設定しているが、テストに失敗した時にRedmineのチケットが自動登録されない

問題6 TortoiseSVNのパッチ機能が腐ってる
外注からパッチで差分を送ってもらうことも考えたが、TortoiseSVNの文字コード認識がおかしく、一度エディタで開いて文字コードを保存し直す必要があった。(ちなみにソースはUTF-8)

問題7 機能ブランチの管理が大変。
一度切るとなかなか戻ってこない。戻すにも準備がかなり必要になる。試しに作ったけどいらなかったブランチも扱いに困る。

問題だけ見ると「何でこんなフローにしたんだ」と自分でも思ってしまうけど、少しずつプラクティスを取り入れた結果うまく連携できてない現状になってしまった。近々Subversionのリポジトリを課管理から本部管理に移行するお仕事があるのでこれを機にこれまでの問題点を解消しようと思っています。

詳細は後半で → Subversion, Git, Redmine, Hudson – 今考えている連携 » tune web

Hudsonでハマった話

10月 30th, 2009

今日会社でHudsonにハマった話。

毎夜のストレステストが落ちてた報告がメールできていて問題に気づきました。
エラーメッセージを見るとHudsonでジョブを起動したときに落ちていたので、前日にアップグレードしたHudsonのバージョンの関係かとSlave周りの設定を見直してました。

結果として間違っていたのはHudsonのバージョンではなく、整理したPluginの問題でした。Mercurialやrubyなど使ってもいないプラグインが多数有ったので一括して使わなくしたのでした。その中にSubversionプラグインがあったのですが、これはHudsonのSubversionサポートを強化してくれるプラグインではなくて、Subversionサポートそのものを提供してくれる物だったんですね。昔はSubversionだけ組み込みで提供してくれていたのでうっかりハマりました。

同じ間違いをする人がいるとも思えませんが、参考まで。

Hudsonのよくわからないエラー

9月 20th, 2009

SCMのポーリングが実行
Updating http://example.com/svn-repos/
FATAL: Unable to call getCredential. Invalid object ID 109
java.lang.IllegalStateException: Unable to call getCredential. Invalid object ID 109
at hudson.remoting.RemoteInvocationHandler$RPCRequest.perform(RemoteInvocationHandler.java:268)
at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:255)
at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:215)
at hudson.remoting.UserRequest.perform(UserRequest.java:104)
at hudson.remoting.UserRequest.perform(UserRequest.java:48)
at hudson.remoting.Request$2.run(Request.java:236)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
at java.lang.Thread.run(Thread.java:619)

Windowsのスレーブで1.317から出るようになったみたい。
Subversionのリポジトリをポーリングしてビルドを動かすようにしているけど、出るときとでないときがあります。1回目はエラーがでて、2回目は出ない感じ。何なんでしょう?

・・・

下のスレッドで議論されている内容が原因みたい。斜め読みだけどSingletonの使い方がおかしいのかな?
Nabble – Hudson dev – Error in SubversionSCM “Unable to call getCredential”
このnabble.comってのはどんなサイトなんだろう? 修正パッチも有ったみたいだけどHudsonのMLには同様の情報は流れてないのかな。

・・・

よくHudsonのバグリストを探してみたら見つかった、これな気がする。
hudson: 課題 4176
現在もステータスはOpenになってるし、問題として認識されているんだろう。
個人的には毎日何回もエラーメールが飛んできて困るので2票ほど投票してみた。結構根が深い問題なのだろうか、気長に待とう。

Hudsonを稼働させてるサーバにVMWare Server2をインストールしたら片方起動しなくなった

4月 2nd, 2009

タイトルの問題に今日の仕事中悩んでました。
きっかけはCentOS 5.3のアップデートで、サーバを再起動するついでに前からやりたかったVMWare Serverのアップデートもやってしまおうかと思ったことでした。

VMWare Server2からはWebインターフェースで仮想マシンにアクセスする仕様になってますが、裏ではTomcatが同梱され動いているようです。んでHudsonを動かすTomcatとVMWare Server2が使うTomcatが何らかの原因で共存できなくて問題が起こったようです。

本当は○○すればこの問題は解決します とまで調べて書きたいのですが、他の業務に押されて調べきれず、結局VMWare Serverのバージョンを元に戻してしまいました。

Javaが得意な方で、どの辺の設定をいじれば良いものか検討がつく方はいましたらコメントで教えてください m(_ _ )m

Hudson 1.273を試してみた

1月 14th, 2009

Hudsonコミッタの id:ssogabeさんに言及されてたのでHudson 1.273を試してみました。

前に書いた不満点に

  • マスタにラベルが割り振れない
  • Windows 64bitでサービス登録できない

の2点がありましたが、2点とも今回のリリースでなおっているとchangelogに記載がありました。

マスタにラベルを振る機能は自分が望んでいた通りのものでした。WindowsとLinuxを混在させた環境を作るためにマスタで直接実行するのをさけ、あえてslaveとして登録させていましたが、この設定は早速削除しました。

もう一点の64bit Windowsでのサービス登録はやっぱりうまく行きませんでした。エラーのスタックトレースはこんな感じでした。

java.io.FileNotFoundException:

http://example.jp:8080/jnlpJars/remoting.jar

at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown
Source)

HudsonのURLが

http://hudson.example.jp:8080

ではなく

http://example.jp:8080/hudson/

なので、どうも要求しているリソースのURLがあってない気がします。これも登録済みのバグなのかな?

2009年1月21日追記
Hudson 1.277でなおったようです。無事に64bit Windowsでもサービス登録できました。
VistaだとUACが悪さをして登録できないようですが、一時的にUACを切ればいけます。

WindowsでのHudson設定に難儀

11月 16th, 2008

WindowsとLinuxの混在環境が構成できたと先週ブログに書いたばかりですが、WindowsではSlaveがいつの間にかオフラインに切り替わってしまう現象が頻発して実運用には使えない状態であることが分かりました。ログとかを眺めていますが、Hudsonに関する情報はまだまだネット上に少なくてバグなのか、自分の設定ミスなのかも切り分けられません。ちなみにエラーメッセージはこんなのです

2008/11/12 9:04:04 hudson.TcpSlaveAgentListener$ConnectionHandler$1 onClosed
警告: Connection #46 terminated
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2554)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1297)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at hudson.remoting.Channel$ReaderThread.run(Channel.java:637)

2008/11/12 9:04:04 hudson.remoting.Channel$ReaderThread run
致命的: I/O error in channel machine1
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2554)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1297)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at hudson.remoting.Channel$ReaderThread.run(Channel.java:637)

2008/11/12 9:03:53 hudson.TcpSlaveAgentListener$ConnectionHandler error
警告: Connection #47 is aborted: machine1 is already connected to this master. Rejecting this connection.

Hudsonの1.262には修正したバグに”Slave installed as a Windows service didn’t attempt automatic reconnection when initiail connection fails. “なんてのがあるようですがこれとは違うようだ… VMWare上のOSをSlaveに使っているのが何かまずいのだろうか。

ついでにWindows環境のSlaveですが、Windows Vista Businessの64bitを使おうとしたところ、Windowsのサービス登録に失敗しました。これもBTSに登録されているバグなんでしょうか?

会社のメールアドレスでHudsonの日本語メーリングリストに登録したから、もうちょっとBTSを探してみて、現象を報告してみよう。

※11/17追記
HudsonをアップグレードしたらSlaveが離脱する問題が解決した模様。
VMWareが影響してネットワークが途中で切断していたのだろうか。
Vista 64bitでサービス登録できないのは相変わらず、エラーメッセージは以下の通り

WMI.WmiException: AccessDenied
場所 WMI.WmiRoot.BaseHandler.CheckError(ManagementBaseObject result)
場所 WMI.WmiRoot.ClassHandler.Invoke(Object proxy, MethodInfo method, Object[] args)
場所 WMI.Win32ServicesProxy.Create(String , String , String , ServiceType , ErrorControl , StartMode , Boolean )
場所 winsw.WrapperService.Run(String[] args)
場所 winsw.WrapperService.Main(String[] args)

HudsonのWindows/Linux混在テスト環境できたよー♪

11月 6th, 2008

ということで、業務の空き時間をちょこちょこ使うことでついにWindows/Linuxの混在ビルド環境ができました。

環境を書いておくと

ホストOS:CentOS 5.2
ゲストOS(VMWare Server): Windows Vista / Ubuntu 8.10

で、HudsonをホストOSに入れTomcatで運用。
WindowsをJNLPで、Ubuntuをsshでslave.jarを呼び出す形でSlaveに追加し、ホストOSも同時実行するインスタンス数はHudsonの設定で0にし、別途Slaveとして追加しています。つまりMaster1台+ Slave3台です。

前はLinuxのSlave追加に悩んでいましたが、理屈が分かってからはWindowsの方が設定に悩みました。
以下Windowsの設定で悩んだことです。

1. WindowsでVisualStudioを使ってビルドするときはSlaveのサービスを起動するユーザをHudsonを動かすユーザにする必要がある。
そうじゃないとビルド時にオブジェクトが一致しないとか言うエラーメッセージが出てビルドができない。
discypusさんで解決情報を見つけたはずなんだけど検索しても見つけた情報が見つからなくなってる orz

2. JNLPでWindowsをSlaveに追加しHudsonをサービスとして起動するとき、Slaveの名称に半角スペースを含んでいるとサービスが起動しない。

3. 自分の環境だとなぜかWindowsのSlaveが一定時間経つとHudsonとの接続がきれ、サービスが勝手に終了してしまった。原因は分からないがWindowsのサービス設定で自動的に再起動するように設定したら大丈夫そう。

まだまだ改善点はありますが、大分ノウハウもたまってきました。

Pages: 1 2 Next