Jenkinsのbuild flow pluginを使うとjobの設定管理が少し楽になる

まとめ

  • Jenkinsのjobの設定管理はリポジトリのバージョンと揃えないと行けないため面倒
  • 全てをスクリプトで実行するのが理想だが、本体の機能を使いたい場合は対応できない
  • build flow pluginがファイルを読み込んで実行できるようになった
  • これにより、Jenkinsのjobを呼び出すスクリプトをリポジトリ内に入れてバージョン管理出来る

Jenkinsのjob設定問題

Jenkinsの大きな問題の一つは、Jenkinsのjob設定をどう管理するかだと思います。

例えばビルド手順を変更する場合、プラグイン設定に後方互換性がないような変更を行うと、
前のバージョンをビルドしたときにエラーになります。

このような場合、通常は最新の変更を取り込む事で解決しますが、
コードフリーズ中のリリースブランチのように、最新の変更を取り込めない場合はこの方法で解決できません。

このような場合、二通りの解決方法が存在します。

全部スクリプトで処理する方法

一つ目が全部スクリプトでやってしまう方法です。
Jenkinsのjobからは単一のスクリプトだけを実行し、その中で全てを行います。

この方法はJenkinsを単なるcronとしてしか使わないため、
全部自分でやる必要がありますが自由度がとても高いのが特徴です。

ですがこの方法では、プラグインや下流jobとの連携、特定の処理だけ別ノードで実行するなど、
Jenkinsの機能が使えなくなります。

新しいJobを作っていく方法

これに対し、jobの変更管理を諦め、どんどん新しいjobを作ってく方法があります。
Jenkinsはjobのコピーが容易なため、後方互換性のない変更を加える段階で新しいjobに切り替え、
以降はそちらでビルドし、過去のバージョン用のビルドが必要なときには残してある前のjobを実行します。

この方法の場合、Jenkinsの機能を利用しつつ、複数のビルド設定を同時に扱うことが出来ますが、
どのバージョンでどのjobを動かせばいいかを保存しておけないため、jobが増えていくと問題になります。

これに対し、build flow pluginを使う事で、どのjobでビルドするかといった情報を、
リポジトリ内に入れてバージョン管理することが出来ます。

build flow pluginでjobの関係をリポジトリに入れる

Jenkinsのbuild flow pluginでは、複数のjobをスクリプトから実行することが出来ます。
Build Flow Plugin

具体的には以下のように書くことで、job1が成功したらjob2を実行するといったことが出来ます。

// 失敗から成功に変わったか判定
def isFixedBuild(result){
  prev = build.previousBuild
  return prev.result != SUCCESS && result == SUCCESS
}

// job1を実行
b = build("job1")
// job1のログを出力する
out.println b.getLog()

if(b.result == SUCCESS){
  // job1が成功していたらjob2を実行
  b = build("job2")

  if (isFixedBuild(b.result)){
    out.println "fixed"
  }else{
    out.println "success"
  }
}

このbuild flow pluginですが、最近の変更でリポジトリ内のファイルを実行することができるようになりました。
そのため、メインのjobがリポジトリ内のスクリプトを読み込んで、ビルド用のjobを呼び出すように構築することで、
二つ目の新しいjobを作っていく方法の問題点だった、リポジトリのバージョンとjobの対応付けが解決します。

残念ながら、job自体の設定は管理出来ないため、設定を変更したい場合はjobを増やしていく必要がありますが、
呼び出しはスクリプトから行うため、ビルドの実行自体はスクリプトを呼ぶだけで済みます。

これは一つ目の全てをスクリプトで行う方法と同じく、リポジトリ内のgroovyファイルを実行する方法になりますが、
Jenkinsのjobをスクリプト内から呼び出せるため、プラグインといったJenkinsの機能を利用できる利点があります。

ただし、別のjobに別れてしまうため、
実行時に設定したパラメーターなどは、呼び出すjob側に一つ一つ明示的に渡す必要があったり、
ファイルの受け渡しを成果物とCopy Artifact Pluginを利用して行う必要があるなど、
job間のデータの受け渡しが面倒になるという問題が生じますので注意が必要です。