Jenkins Multibranch Pipeline でワークスペースのパスが長過ぎてエラーになるのを回避する
Windows Server 上で動作させている Jenkins にて。
Multibranch Pipeline を使うと、Git ブランチごとにワークスペースディレクトリが自動生成されるのだが、このディレクトリ名にユニーク ID と思われるランダムな文字列が付与される。これのせいで、Git チェックアウト時にファイルのフルパスが長くなり過ぎて、ビルドが失敗してしまった。
以下のような Filename too long
といったコンソールログが表示される。
hudson.plugins.git.GitException: Command "git.exe checkout -f 2cea7d8eb9185899c01d2ffc86872f584da2e60c" returned status code 1:
stdout:
stderr: error: unable to create file edgemagic-nextgen-core/src/test/resources/dbunit_test_data/com/cybra/edgemagic/service/EmObjectServiceTest/data/testInstances_create_dataRequiresData.xml: Filename too long
そこで考えたのが、ワークスペースディレクトリの名前を短くできないか、ということで、調べてみるとやり方があった。
Declarative Pipeline の場合、ws()
ステップでワークスペースディレクトリを変更できる他、agent {}
ブロック内で customWorkspace
オプションを指定すると任意のパス配下をワークスペースとして使えるようになるのだ。
- 参考 : JENKINS-41118 Allow custom workspaces in declarative pipeline - Jenkins JIRA …
customWorkspace
指定の例 - 参考 : JENKINS-38706 Workspace directory names mangled in multibranch pipeline - Jenkins JIRA …
customWorkspace "${JENKINS_HOME}/Workspace/${URLDecoder.decode(JOB_NAME)}/${BUILD_NUMBER}"
という例を挙げているが、URLDecoder が使えなかった - 参考 : New Declarative Pipeline features in 1.1 · GitHub …
customWorkspace
は相対パスでもフルパスでも書けるようだ
早速書いてみるとこんな感じ。
pipeline {
agent {
label {
label ""
// ワークスペースディレクトリ配下のディレクトリ名を変える
// ブランチ名に「feat/」が含まれていれば消す。それ以外の「/」は「-」にする
// 「my-multi-job-【ブランチ名の省略形】-【ビルド番号】」にする
customWorkspace "${JENKINS_HOME}/workspace/my-multi-job-${BRANCH_NAME.replaceAll("feat/", "").replaceAll("/", "-")}-${BUILD_NUMBER}"
}
}
stages {
steps {
echo "${pwd()}"
}
}
}
Jenkins が設定する環境変数を用いて、元々のワークスペースディレクトリ ${WORKSPACE}
と同階層に「my-multi-job-【ブランチ名の省略形】-【ビルド番号】
」という名前のディレクトリを作り、通常よりも短いディレクトリ名で済ませられるようにした。
Jenkins が提供する環境変数の一例は以下のとおり。
環境変数 | 概要 |
---|---|
${JENKINS_HOME} |
Jenkins のルートパス |
${WORKSPACE} |
デフォルトのワークスペースのパス。デフォルトだと ${JENKINS_HOME}/workspace/${JOB_NAME} かな |
${BUILD_NUMBER} |
ビルド番号 (1 からの連番になる) |
${JOB_NAME} |
ジョブ名 |
${BRANCH_NAME} |
マルチブランチ・パイプラインの時だけ参照可能 |
また、処理部分で使用している ${pwd()}
は、環境変数ではないが、カレントディレクトリを確認できる。
Jenkins の中身は Java なので、例のように replaceAll()
という Java String のメソッドが使える。この replaceAll()
で \
記号を扱う時は \\\\
と書かないと、PatternSyntaxException: Unexpected internal error near index 1
エラーが出るので注意。replaceAll("\\\\", "-")
と書くことで、\
記号を -
に置換できる、というワケだ。
コレでワークスペースまでのパスを短くでき、チェックアウトするファイルの長さにも耐えられるようになった。一件落着。