如何使用声明性Jenkins管道在同一节点上运行多个阶段?
目标如何使用声明性Jenkins管道在同一节点上运行多个阶段?,jenkins,jenkins-pipeline,Jenkins,Jenkins Pipeline,目标 在同一节点上运行声明性Jenkins管道的多个阶段 设置 这只是说明问题的一个最小示例。有两个Windows节点“Windows-slave1”和“Windows-slave2”都标有“Windows”标签 注意:我的real Jenkins文件不能使用全局代理,因为需要在不同的节点(例如Windows和Linux)上运行多组阶段 预期行为 Jenkins根据标签选择“阶段1”中的一个节点,并在“阶段2”中使用相同的节点,因为变量windowsNode已更新为“阶段1”中选择的节点 实际行
在同一节点上运行声明性Jenkins管道的多个阶段 设置
这只是说明问题的一个最小示例。有两个Windows节点“Windows-slave1”和“Windows-slave2”都标有“Windows”标签 注意:我的real Jenkins文件不能使用全局代理,因为需要在不同的节点(例如Windows和Linux)上运行多组阶段 预期行为
Jenkins根据标签选择“阶段1”中的一个节点,并在“阶段2”中使用相同的节点,因为变量windowsNode已更新为“阶段1”中选择的节点 实际行为
“阶段2”有时在与“阶段1”相同的节点上运行,有时在不同的节点上运行。请参见下面的输出 Jenkinsfile
#!棒极了
windowsNode='windows'
管道{
一号特工
舞台{
阶段(“阶段1”){
代理人{
标签窗口节点
}
台阶{
剧本{
//所有后续步骤都应在同一windows节点上运行
windowsNode=节点名称
}
echo“windowsNode:$windowsNode,NODE\u NAME:$NODE\u NAME”
}
}
阶段(“阶段2”){
代理人{
标签窗口节点
}
台阶{
echo“windowsNode:$windowsNode,NODE\u NAME:$NODE\u NAME”
}
}
}
}
输出
[Pipeline] stage
[Pipeline] { (Stage 1)
[Pipeline] node
Running on windows-slave2 in C:\Jenkins\workspace\test-agent-allocation@2
[Pipeline] {
[Pipeline] script
[Pipeline] {
[Pipeline] }
[Pipeline] // script
[Pipeline] echo
windowsNode: windows-slave2, NODE_NAME: windows-slave2
[Pipeline] }
[Pipeline] // node
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Stage 2)
[Pipeline] node
Running on windows-slave1 in C:\Jenkins\workspace\test-agent-allocation
[Pipeline] {
[Pipeline] echo
windowsNode: windows-slave2, NODE_NAME: windows-slave1
[Pipeline] }
[Pipeline] // node
[Pipeline] }
[Pipeline] // stage
[Pipeline] End of Pipeline
Finished: SUCCESS
你知道设置有什么问题吗?我想这就是Jenkins文件的解析和执行方式
其他建议?最初设置windowsNode时,可能有一个Jenkins API可以根据“windows”标签选择节点。将
代理无
替换为代理任何
您可以在脚本块内定义阶段。这些阶段是在给定代理中运行的父阶段的子阶段。这是我在一个与你类似的用例中必须使用的方法
#!棒极了
windowsNode='windows'
管道{
一号特工
舞台{
阶段(‘阶段A’){
代理人{
标签窗口节点
}
台阶{
剧本{
阶段('阶段1'){
windowsNode=节点名称
echo“windowsNode:$windowsNode,NODE\u NAME:$NODE\u NAME”
}
阶段(“阶段2”){
echo“windowsNode:$windowsNode,NODE\u NAME:$NODE\u NAME”
}
}
}
}
}
}
我发现它的工作原理与您预期的一样
#!groovy
windowsNode = 'windows'
pipeline {
agent none
stages {
stage('Stage 1') {
steps {
node(windowsNode) {
script {
// all subsequent steps should be run on the same windows node
windowsNode = NODE_NAME
}
echo "windowsNode: $windowsNode, NODE_NAME: $NODE_NAME"
}
}
}
stage('Stage 2') {
steps {
node(windowsNode) {
echo "windowsNode: $windowsNode, NODE_NAME: $NODE_NAME"
}
}
}
}
}
自1.3版声明性管道插件以来,这一功能得到了官方支持。 官方称之为“连续阶段”
此处正式宣布:您的第2阶段没有使用重命名的变量。如果您将
windowsNode='windows'
更改为windowsNode='asdf'
,那么您应该会看到一个“没有带有标签'asdf'的节点”错误,这意味着您的stage 2仍在运行label'windows'
而不是label'windows-slave2'
。但是,我尝试了stage(“stage 2”){environment{someVariable=“$windowsNode”}代理{label env.someVariable}..
虽然它分配了一个节点并且没有“缺少属性”错误(意思是代理
至少知道someVariable存在),它不起作用。如果我打印env.someVariable
的值,它就是节点名,因此尽管它可以看到正确的windowsNode
变量,但我怀疑someVariable
在agent
指令中处于某种空白状态,导致它运行类似agent label''的东西,而不是agent标签“windows-slave2”
。我还尝试了环境{someVariable=“\'$windowsNode\”}
,这使得变量'windows-slave2'
而不仅仅是windows-slave2
,但它仍然在我的两个测试节点之间随机分配(尽管变量或标签名称仍然没有错误)。这不会有帮助。使用代理any
意味着如果步骤中未提供代理,则它将尝试在任何可用节点上运行。OP希望这些步骤在特定节点上运行。这是不正确的,在管道开始处指定代理会为整个脚本分配代理。如果从属节点也有两个执行器,我已经阻止了这项工作的两个执行器,是否可以用这种方法使用并行阶段?很好的功能,但是如果必须在阶段序列中分配两个单独的节点:stage1-nodeA stage2-nodeB stage3-nodeA stage4-nodeA?是否可以将节点名称保存到变量nodeA | B和nodeA中阶段3和阶段4在代理{node nodeA | B}中使用它?当序列块本身是并行阶段的一部分时,如果我尝试这样做,我会遇到语法错误。我在发起此开发的问题中看到类似的抱怨。这一点并不少见,但实现此功能的人似乎没有想到。如果有办法使其工作,我会很高兴听到。事实上,我不得不使用管道环境中定义的变量,在脚本块的第一个seq阶段中设置,并在不使用env.前缀的情况下写入/读取。
pipeline {
agent none
stages {
stage("check code style") {
agent {
docker "code-style-check-image"
}
steps {
sh "./check-code-style.sh"
}
}
stage("build and test the project") {
agent {
docker "build-tools-image"
}
stages {
stage("build") {
steps {
sh "./build.sh"
}
}
stage("test") {
steps {
sh "./test.sh"
}
}
}
}
}
}