首页 文章

如何在声明管道中等待用户输入而不阻塞重量级执行程序

提问于
浏览
12

我正在重建现有的构建管道作为jenkins声明管道(多分支管道)并且在处理构建传播时遇到问题 .

在打包并存储所有相关文件之后,管道应该等待用户输入以触发部署 .

如果我只是添加一个输入步骤,则阻止当前的构建节点 . 由于这个 Actuator 很重,我想将这一步移到更轻量级的机器上 .

最初我作为脚本管道完成了工作,只创建了两个不同的 node('label') 块 . 有没有办法让我用声明性语法做类似的事情?

node('spine') { 
    stage('builder') {
        sh 'mvn clean compile'
        stash name: 'artifact', includes: 'target/*.war'
    }
}
node('lightweight') {
    stage('wait') {
        timeout(time:5, unit:'DAYS') {
            input message:'Approve deployment?'
        }
    }
    // add deployment stages
}

我已经尝试了几件事:

在顶层配置代理并将其他代理配置添加到传播步骤,但随后我有两个 Actuator 阻塞,因为顶级定义的构建节点未停止 .

在顶级设置 agent none 并在每个步骤中配置代理 . 那么git checkout就不存在于第一个节点上 .

EDIT 1

我根据你的建议重新配置了我的管道,它目前看起来像这样:

pipeline {
agent none
tools {
    maven 'M3'
}
stages {
    stage('Build') {
        agent { label 'spine' }
        steps {
            checkout scm // needed, otherwise the workspace on the first step is empty
            sh "mvn clean compile"
        }
    }
    stage('Test') {
        agent { label 'spine' }
        steps {
            sh "mvn verify" // fails because the workspace is empty aggain
            junit '**/target/surefire-reports/TEST-*.xml'
        }
    }
}
}

此构建将失败,因为工作区不会在步骤之间进行,因为它们不在同一执行程序上运行 .

EDIT 2

显然,有时步骤在同一 Actuator 上运行,有时则不会 . (我们根据需要在我们的mesos / dcos集群上生成构建从属,因此更改执行者中间构建将是一个问题)

只要代理定义中的标签不变,我希望jenkins只运行当前执行程序 .

3 回答

  • 1

    请参阅best practice 7:不:在节点块中使用输入 . 在声明性管道中,节点选择是通过 agent 指令完成的 .

    文档here描述了如何为pipline定义 none ,然后使用阶段级 agent 指令在所需节点上运行阶段 . 我也尝试了相反的方法(在某个节点上定义一个全局代理,然后在阶段级别为输入定义 none ),但这不会释放一个或多个特定阶段的从属 .

    这是our pipeline的结构:

    pipeline {
      agent none
      stages {
        stage('Build') {
          agent { label 'yona' }
          steps {
            ...
          }
        }
        stage('Decide tag on Docker Hub') {
          agent none
          steps {
            script {
              env.TAG_ON_DOCKER_HUB = input message: 'User input required',
                  parameters: [choice(name: 'Tag on Docker Hub', choices: 'no\nyes', description: 'Choose "yes" if you want to deploy this build')]
            }
          }
        }
        stage('Tag on Docker Hub') {
          agent { label 'yona' }
          when {
            environment name: 'TAG_ON_DOCKER_HUB', value: 'yes'
          }
          steps {
            ...
          }
        }
      }
    }
    

    通常,构建阶段在标记为“yona”的构建从属上执行,但输入阶段在主服务器上运行 .

  • 23

    在顶部使用agent none并为除包括输入步骤的阶段之外的每个阶段定义代理 .

    来源:讨论Use a lightweight executor for a declarative pipeline stage (agent none)

    更新:你的意思是“第一个节点上没有git checkout”?请展示你到目前为止的声明性管道 .

  • 1

    另一种方法是使用表达式指令和beforeAgent,它跳过“决定”步骤并避免弄乱“env”全局:

    pipeline {
        agent none
    
        stages {
            stage('Tag on Docker Hub') {
                when {
                    expression {
                        input message: 'Tag on Docker Hub?'
                        // if input is Aborted, the whole build will fail, otherwise
                        // we must return true to continue
                        return true
                    }
                    beforeAgent true
                }
    
                agent { label 'yona' }
    
                steps {
                    ...
                }
            }
        }
    }
    

相关问题