JenkinsのジョブでSubversionで複数個所からチェックアウトした際に、
一番大きいリビジョン番号が欲しかったり、比較したい事がありました。
通常のジョブでは SVN_REVISION_1、SVN_REVISION_2、... を
参照する事で比較など可能でしたが、pipelineには実装されていません。
当時は、良い方法がわからずWSHにディレクトリ名渡して
中でリビジョン番号比べて、その先の処理も全部やっちゃうやつ作ってましたが
そんな事をする必要が無いとわかったのでメモとして記事にします。
pipeline テストコード
「CI_TEST/trunk」にA~Zまでのディレクトリがあるとします。
その中から、A,B,Cだけをチェックアウトし一番大きいリビジョンを表示するサンプルです。
node(){
def checkOutRoot = 'file://CI_TEST/trunk'
def checkOutDir = [ "A","B","C" ]
ws('D:\\CI_TEST'){
def revision_max = 0
stage('checkout'){
// checkoutディレクトリ設定
def locations = []
for (def dir : checkOutDir) {
locations.push([
cancelProcessOnExternalsFail: true,
credentialsId: '',
depthOption: 'infinity',
ignoreExternalsOption: true,
local: './' + dir,
remote: checkOutRoot + '/' + dir
])
}
checkout([
$class: 'SubversionSCM',
locations: locations,
workspaceUpdater: [$class: 'UpdateUpdater']
])
// checkoutディレクトリ設定から、ひとつずつリビジョンを確認する
for (def location : locations) {
def command = "@svn log ${location.local} -l 1"
def out = bat(returnStdout:true, script:command)
def rev_str = out.find(/(r)([0-9]+)/){ it[2] }
def rev = Integer.parseInt( rev_str )
if ( rev > revision_max ) revision_max = rev
}
echo "max : $revision_max"
}
}
}
コード解説
pipeline の bat,sh,powershell には出力結果を返す設定がある
Jenkins : Pipeline: Nodes and Processes
https://jenkins.io/doc/pipeline/steps/workflow-durable-task-step/
def command = "@svn log ${location.local} -l 1"
def out = bat(returnStdout:true, script:command)
そらそうでしょ。と言われるかも知れませんが、Pipeline Syntax を使って初めてGenerateして以降、何も確認していませんでした。
※Commandに「@」を付けているのは、出力結果に実行コマンドが含まれてしまうから
「高度な設定」があったのでそれを開けば、わかったはずですが、
通常のジョブでは元々エラーレベルに関する設定しかなかったので...
今回初めてマニュアルを読んで、Pipeline Syntax の高度な設定を開いてびっくりしました。
svn log からリビジョン番号が取得できる
svn log を使ってチェックアウトしたディレクトリのリビジョンを確認します
svn log ./A -l 1
------------------------------------------------------------------------
r8 | kazu | 2018-12-30 19:02:17 +0900 (日, 30 12 2018) | 1 line
------------------------------------------------------------------------
-l Number -l 1 とすることで一件だけ表示できる
この出力結果を文字列として受け取り、正規表現で抜き出すだけです。
def rev_str = out.find(/(r)([0-9]+)/){ it[2] }
def rev = Integer.parseInt( rev_str )
最後に
リビジョン番号を取得した事よりも、ハッとしたのは
・ちゃんとリファレンスは読もう
・なんとなく動いたからってそのまま使用しない
・出力結果取れるならもうなんでもできるな!
という事です。
参考リンク
Jenkins : Pipeline Steps Reference
https://jenkins.io/doc/pipeline/steps/
svn log
http://www.thekyo.jp/manual/subversion/svn.ref.svn.c.log.html