ジョブの遅延連係っぽいことやってみた(Jenkins Adaptiveっていう変態プラグイン見つけた)

おっさん臭い言い方するとディレイドバッチ?やりたいことはこんな事。

  • ジョブAとジョブBがある。
  • ジョブBは定時起動するが,実行条件に直近のジョブAのビルドが成功している事を加えたい。

やりたくないことは「ジョブAのビルド完了後,即ジョブBを実行したくない」。なんで,ジョブBを下流プロジェクトに設定するのは却下。


具体的にはどんなこと?というと。

  • ジョブAはいわゆる普通の継続ビルド
  • ジョブBはジョブAの成果物を定期デプロイするジョブ。なんで,ジョブAがコケてたら動いて欲しくない。

よくよく考えてみると,ジョブAの成果物の置き場所を工夫すればジョブBは定時起動しつづけるだけでも十分だった気もするが,これ書いてる今気づいたんだから仕方ない。:-P
#ちなみに,ジョブとプロジェクトは同義ね。基本「ジョブ」って書きます。


最終的な解決策にたどり着くまでに,いろいろプラグインあさってみたので,それぞれの評価を残しておく。

URL SCMプラグイン

http://wiki.jenkins-ci.org/display/JENKINS/URL+SCM


ジョブBに登録して,ジョブAの「最新の成功ビルド(lastSuccessfulBuild)」のURLを監視させよう思ったんだけど,ビルドが更新されてもその変化を検知してくんなかったので却下。
どうも指定したURLのlast-modifiedみてるっぽいんだけど,Jenkinsさんがそれ返してくんないみたい。

URL Change Triggerプラグイン

http://wiki.jenkins-ci.org/display/JENKINS/URL+Change+Trigger


URL SCMみたいなやつ。ただこれ,指定したURLにコンテンツがある・無ししかチェックしないのと,監視タイミングが1分間隔で固定ってのがイマイチで使えなかった。

Groovyプラグイン

http://wiki.jenkins-ci.org/display/JENKINS/Groovy+plugin


もうJenkinsスクリプトに頼るか思ったんだけど,これだとビルドが走っちゃうので,監視対象(ビルドA)が不安定だったら自身をコカさないといけない。あたしがやりたいのはビルドトリガーなんだよう。ってことで却下。

Files Found Triggerプラグイン

http://wiki.jenkins-ci.org/display/JENKINS/Files+Found+Trigger


ファイルのある・無しチェックするプラグイン。ジョブAのビルドに「成功したらフラグファイル作る」みたいなしょっぱいビルドを追加して,ジョブBでそのファイルの有無を監視させた。
監視ファイルがフルパス指定なので正直美しくないけど,なんつーか,まー使い古された手なんで確実っちゃあ確実。実際これでしばらく運用してた。


欠点といえば,テストが失敗するとかいわゆるビルドが不安定なのを検知するのが得意じゃない事かな。

Jenkins Adaptiveプラグイン

http://wiki.jenkins-ci.org/display/JENKINS/Jenkins+Adaptive+Plugin


今日見つけたのがこれ。なんでちゃんと運用で回してないんだけど,たぶん,これが理想的。


プラグイン作るまでもないJenkinsさんの拡張ポイントをその場で書き換えちゃう,なんともステキな変態プラグイン。てか,ちょっと難しすぎてワケ分かんない。><


そいで試行錯誤した結果,こんな構成で解決させてみた。プラグイン入れるとジョブの設定に'Adaptive Plugin Script'ってのが出来るので,そこにこんなスクリプトを登録してみる(ちなみジョブBのほうね)。

jenkins {
  scm { 
    def targetPrj = project("jobA")
    poll {
       def lastBuild = targetPrj.lastBuild.timeInMillis
       def lastSuccessBuild = targetPrj.lastSuccessfulBuild.timeInMillis
       println "lastBuild:${lastBuild}"
       println "lastSuccessBuild:${lastSuccessBuild}"
       if (lastBuild == lastSuccessBuild) {
         hudson.scm.PollingResult.BUILD_NOW
       } else {
         hudson.scm.PollingResult.NO_CHANGES
       }
    }
  } 
}

何してるのかというと,

  • scmを拡張してジョブAのステータスを監視
  • ジョブAのlastBuildとlastSuccessfulBuildが同じ値だったら,最新のビルドは成功してるんで,自分も実行さす(poll { PollingResult.BUILD_NOW })。
  • lastBuild != lastSuccessfulBuildだったらスキップする(poll { PollingResult.NO_CHANGES })。

ソースコード管理システムにもAdaptivePluginってあるんで,それを選び,あとはビルド・トリガのSCMをポーリングを設定して完了。あら,とってもいい感じ。


ps.
正直言うと,まだHudsonさんを使っているので,PollingResult.BUILD_NOWやPollingResult.NO_CHANGESがあんな書いてあるけど,Jenkinsさんだとたぶん完全修飾子にしなくてもイケると思う。