首页 文章

如何使用声明性Jenkins管道在同一节点上运行多个阶段?

提问于
浏览
12

Goal
在同一节点上运行声明性Jenkins管道的多个阶段 .

Setup
这只是显示问题的最小示例 . 有2个Windows节点"windows-slave1"和"windows-slave2"都标有标签"windows" .

注意:我真正的Jenkinsfile不能使用全局代理,因为有一些阶段需要在不同的节点上运行(例如Windows与Linux) .

Expected Behaviour
Jenkins根据标签选择"Stage 1"中的一个节点,并在"Stage 2"中使用相同的节点,因为变量windowsNode已更新为"Stage 1"中选择的节点 .

Actual Behaviour
"Stage 2"有时在同一个节点上运行,有时在与"Stage 1"不同的节点上运行 . 请参阅下面的输出 .

Jenkinsfile

#!groovy

windowsNode = 'windows'

pipeline {
  agent none
  stages {
    stage('Stage 1') {
      agent {
        label windowsNode
      }
      steps {
        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') {
      agent {
        label windowsNode
      }
      steps {
        echo "windowsNode: $windowsNode, NODE_NAME: $NODE_NAME"
      }
    }
  }
}

Output

[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

任何想法设置有什么问题?我想这是Jenkinsfile的解析和执行方式 .

其他建议?也许在最初设置windowsNode时,有一个Jenkins API可以根据"windows"标签选择节点 .

4 回答

  • 6

    您可以在脚本块中定义阶段 . 这些阶段是在给定代理中运行的父阶段的一些子阶段 . 这是我必须在类似用例中使用的方法而不是你的方法 .

    #!groovy
    
    windowsNode = 'windows'
    
    pipeline {
      agent none
      stages {
        stage('Stage A') {
          agent {
            label windowsNode
          }
          steps {
            script {
    
              stage('Stage 1') {        
                windowsNode = NODE_NAME
                echo "windowsNode: $windowsNode, NODE_NAME: $NODE_NAME"
              }
    
              stage('Stage 2') {
                echo "windowsNode: $windowsNode, NODE_NAME: $NODE_NAME"
              }
            }
          }
        }
      }
    }
    
  • -2

    从Declarative Pipeline插件的1.3版本开始,这是官方支持的 . 它被官方称为“顺序阶段” .

    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"
                       }
                   }
                }
            }
        }
    }
    

    官方公告:https://jenkins.io/blog/2018/07/02/whats-new-declarative-piepline-13x-sequential-stages/

  • 2

    agent any 替换 agent none

  • 5

    我发现这可以像你期望的那样工作

    #!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"
                    }
                }
            }
        }
    }
    

相关问题