2015年6月1日月曜日

[Jenkins] Groovy でマトリックス生成

追記: この記事には誤りがあります。詳細は記事末尾の追記をご覧ください。

Jenkins のマトリックス構成ジョブでマトリックスをもっと柔軟に作成したいことってありませんか?

例えば、特定のラベルが付いている すべてのスレーブ でテストを実行したい場合、該当するスレーブで軸を作ることになります。
ラベルで軸を作ると、1つのマトリックスしかできないので1回のビルドで実行されるスレーブも1つで、しかもどのスレーブが選ばれるかもわかりません。


欲しいのはこれじゃないです。
目的は、1回のビルドで該当するスレーブすべてで実行することです。
正攻法だと、該当するスレーブを自分で判断して登録していくことになると思います。

該当スレーブが少なければいいのですが、
たくさんあったり、スレーブの設定がよく変わったりする場合は、とてもメンドクサイです。
そこで、GroovyAxis plugin を使いましょう!

GroovyAxis
GroovyAxis plugin ではその名の通り、Groovy script でマトリックスの軸を設定できます。

まずは、プラグインマネージャーからインストールをしてください。
インストールするとマトリックス構成プロジェクトの設定の「軸の追加」に、「GroovyAxis」が追加されます。


これを選ぶと下のような設定が追加されるので、「Groovy Expression」に Groovy を記述します。


サンプル
基本
GroovyAxis のルールとして、配列を return する必要があります。そして、その配列要素が軸になります。
まずは、簡単なサンプルで動作を確認してみましょう。
def result = []
(1..3).each {
   result += "Axis"+it
}
return result
上記スクリプトを Groovy Expression に記入してください。
その下の「Test the Groovy script」ボタンで実行結果を確認できますので、保存する前に確認しておくとよいでしょう。

保存すると、以下のように Axis1,Axis2,Axis3 の3つのマトリックスができます。


すべてのスレーブ
冒頭の目的を達するには、スレーブの情報を知る必要があります。
まずは、スレーブを列挙し、それをマトリックス化します。
def result = []
def jenkins = hudson.model.Hudson.instance
def slaves = jenkins.slaves
slaves.each {
    result += it.getSelfLabel().getName()
}
return result

特定のラベルがあるスレーブ
次に、ラベルを参照し、目的のラベルがあったらマトリックス化します。
def result = []
def jenkins = hudson.model.Hudson.instance
def slaves = jenkins.slaves
slaves.each { slave ->
    slave.getAssignedLabels().find {
        if( it.getName() == "vs2015" ) {
            result += slave.getSelfLabel().getName()
            return true
        }
    }
}
return result

これで、冒頭の目的が達成出来ました。
Groovy script からは色んな情報を参照できるので、他にも面白い使い方ができると思います。
是非、試してみてください。

さらに便利に…
さてこのマトリックですが、スレーブのラベルを付け替えたり、スレーブを増減させた時に、自動で追従させたいと思いませんか?

できたらいいですねー・・・



・・・すみません。わかりません。
今のところ、「設定ページを開いて保存をする」というのを手作業でやる必要があります。
誰か方法を知っていたら教えてくださいm(__)m


追記
意図したスレーブで実行されてませんでした!!
大変申し訳ありませんでした

どうやら、スレーブの軸ではなく、ユーザー定義の軸と同じ挙動のようで、スレーブ軸の設定として Groovy Axis は使えませんでした。
こちらも、解決策がないかもう少し調べてみます。

追記2 - 回避策
根本的な解決とはいかないが、回避策を書いておきます。

組み合わせフィルターを使う


  1. スレーブ軸を追加し、可能性のあるスレーブをすべてチェックする
  2. 組み合わせフィルターを有効にする
  3. フィルターの式を「label==label2」のように、スレーブ軸名==GroovyAxis名とする
設定は以上です。


余分なマトリックスができてしまいますが、目的は達成できます。
(見た目がかなり悪いですが、対象外のスレーブは未実行になってます。)

Matrix Groovy Execution Strategy Plugin を使う
Matrix Groovy Execution Strategy Plugin は、GroovyAxis Plugin とは違い、組み合わせフィルターのところで Groovy script が使えます。


  1. スレーブ軸を追加し、可能性のあるスレーブをすべてチェックする
  2. 組み合わせフィルターを有効にする
  3. 実行方法を「Groovy Script Matrix Executor Storategy」に変更
  4. Groovy Script に以下のようなスクリプトを記述

def list = []
def slaves = jenkins.slaves
slaves.each { slave ->
    slave.getAssignedLabels().find {
        if( it.getName() == "vs2015" ) {
            list += slave.getSelfLabel().getName()
            return true
        }
    }
}

combinations.each {
    if( list.find { l -> it.label == l } ) {
         result[it.label] = result[it.label] ?: []
         result[it.label] << it
    }
}

execution.listener.logger.println result

return result


ビルド結果はこんな感じです。フィルターよりもすっきりしましたね。
また、この方法であればスレーブの設定が変わった場合にも追従が可能です。

とりあえず、今回は Matrix Groovy Execution Strategy Plugin を使った方法を採用したいと思います。

0 件のコメント:

コメントを投稿