How to wait for user input in a Declarative Pipeline without blocking a heavyweight executor
我正在将现有构建管道重建为 jenkins 声明式管道(多分支管道),但在处理构建传播时遇到问题。
在打包并存储所有相关文件后,管道应该等待用户输入以触发部署。
如果我只是添加一个输入步骤,当前的构建节点就会被阻止。由于这个 executor 很重,我想把这一步移到更轻的机器上。
最初我是作为脚本管道完成这项工作的,只是创建了两个不同的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 } |
我已经尝试了几件事:
在顶级配置代理并向传播步骤添加额外的代理配置,但随后我有两个执行程序阻塞,因为顶级定义的构建节点没有停止。
在顶级设置
编辑 1
我按照你的建议重新配置了我的管道,它目前看起来像这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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' } } } } |
此构建将失败,因为工作区不会在步骤之间延续,因为它们不在同一个执行器上运行。
编辑 2
显然有时这些步骤会在同一个执行器上运行,有时则不会。 (我们根据需要在我们的 mesos/dcos 集群上生成 build slaves,所以改变 executor mid build 将是一个问题)
我希望 jenkins 只与当前执行程序一起运行,只要代理定义中的标签不改变。
参见最佳实践 7:Dona€?t:在节点块中使用输入。在声明式管道中,节点选择是通过
此处的文档描述了如何为管道定义
这是我们管道的结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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\ yes', 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"的构建从属设备上执行,但输入阶段在主设备上运行。
另一种方法是使用表达式指令和 beforeAgent,它会跳过"决定"步骤并避免与"env"全局混淆:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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 { ... } } } } |
我知道这个线程很旧,但我相信除了存储之外,"编辑 2"问题的解决方案是使用嵌套阶段。
https://jenkins.io/blog/2018/07/02/whats-new-declarative-piepline-13x-sequential-stages/#running-multiple-stages-with-the-same-agent-or-环境或选项
根据本页:
... if you are using multiple agents in your Pipeline, but would like to be sure that stages using the same agent use the same workspace, you can use a parent stage with an agent directive on it, and then all the stages inside its stages directive will run on the same executor, in the same workspace.
这是提供的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | pipeline { agent none stages { stage("build and test the project") { agent { docker"our-build-tools-image" } stages { stage("build") { steps { sh"./build.sh" } } stage("test") { steps { sh"./test.sh" } } } post { success { stash name:"artifacts", includes:"artifacts/**/*" } } } stage("deploy the artifacts if a user confirms") { input { message"Should we deploy the project?" } agent { docker"our-deploy-tools-image" } steps { sh"./deploy.sh" } } } } |
在顶部使用无代理,并为除了包括输入步骤的阶段之外的每个阶段定义代理。
来源:使用轻量级执行器进行声明性管道阶段(无代理)中的讨论
更新:"第一个节点上不存在 git checkout"是什么意思?请展示到目前为止您对声明性管道的了解。
OP 的问题是如何"在声明式管道中等待用户输入而不阻塞......"。这似乎不可能。尝试使用 agent: none 不会释放声明式管道中的构建执行程序。
这个:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | pipeline { agent none stages { stage('Build') { agent { label 'big-boi' } steps { echo 'Stubbed' } } stage('Prompt for deploy') { agent { label 'tiny' } steps { input 'Deploy this?' } } stage('Deploy') { agent { label 'big-boi' } steps { echo"Deploying" build job: 'deploy-to-higher-environment' } } } } |
...运行时,如下所示:
...还有这个: