use*_*963 5 jenkins jenkins-pipeline
我有一个有点独特的设置,我需要能够动态加载位于我正在构建的 src 之外的 Jenkinsfiles。Jenkinsfiles 本身通常调用node(),然后调用一些构建步骤。这会导致多个执行器不必要地被消耗,因为我需要已经调用了 node() 才能使用加载步骤来运行 Jenkinsfile,或者如果我将 Jenkinsfile 作为字符串读取并执行它,则执行 groovy。
我今天的工作用户界面中有什么:
@Library(value='myGlobalLib@head', changelog=fase) _
node{
load "${JENKINSFILES_ROOT}/${PROJECT_NAME}/Jenkinsfile"
}
Run Code Online (Sandbox Code Playgroud)
加载的 Jenkinsfile 通常也会调用 node()。例如:
node('agent-type-foo'){
someBuildFlavor{
buildProperty = "some value unique to this build"
someConfig = ["VALUE1", "VALUE2", "VALUE3"]
runTestTarget = true
}
}
Run Code Online (Sandbox Code Playgroud)
这会导致管道运行期间消耗 2 个执行程序。理想情况下,我加载 Jenkinsfiles 时无需先调用 node(),但每当我尝试时,我都会收到一条错误消息,指出:
"Required context class hudson.FilePath is missing
Perhaps you forgot to surround the code with a step that provides this, such as: node"
Run Code Online (Sandbox Code Playgroud)
有没有办法在没有 hudson.FilePath 上下文的情况下加载 Jenkinsfile 或执行 groovy?我似乎在文档中找不到任何内容。我现在要预处理 Jenkinsfiles 以删除它们对 node() 的初始调用,并使用 Jenkinsfile 使用的值调用 node() ,然后加载文件的其余部分,但是,这有点太多了脆弱让我感到高兴。
当使用load步骤 Jenkins 评估文件时。您可以将 Jenkinsfile 的逻辑包装到一个函数中(run()在我的示例中命名),以便它会加载但不会自动运行。
def run() {
node('agent-type-foo'){
someBuildFlavor{
buildProperty = "some value unique to this build"
someConfig = ["VALUE1", "VALUE2", "VALUE3"]
runTestTarget = true
}
}
}
// This return statement is important in the end of Jenkinsfile
return this
Run Code Online (Sandbox Code Playgroud)
从您的作业脚本中调用它,如下所示:
def jenkinsfile
node{
jenkinsfile = load "${JENKINSFILES_ROOT}/${PROJECT_NAME}/Jenkinsfile"
}
jenkinsfile.run()
Run Code Online (Sandbox Code Playgroud)
这样就不再有嵌套块,因为第一个块在调用函数node之前关闭。run()