问题描述
我正在将现有的构建管道重建为 jenkins 声明式管道(多分支管道),并且在处理构建传播时遇到问题.
I'm rebuilding an existing build pipeline as a jenkins declarative pipeline (multi-branch-pipeline) and have a problem handling build propagation.
在打包和存储所有相关文件后,管道应该等待用户输入以触发部署.
After packaging and stashing all relevant files the pipeline is supposed to wait for user input to trigger deployment.
如果我只是添加一个输入步骤,当前的构建节点将被阻止.由于这个执行器很重,我想把这一步移到更轻量级的机器上.
If i just add an input step the current build-node is blocked. As this executor is pretty heavy i would like to move this step to a more lightweight machine.
最初,我将这项工作作为脚本管道完成,并创建了两个不同的 node('label')
块.有没有办法让我用声明性语法做类似的事情?
Initially i did the job as a scripted pipeline and just created two different node('label')
blocks. is there a way for me to do something similar with the declarative syntax?
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
}
我已经尝试了几件事:
在顶层配置代理并在传播步骤中添加一个额外的代理配置,但是我有两个执行程序阻塞,因为顶层定义的构建节点没有停止.
configuring the agent on the top-level and adding an additional agent config to the propagation step, but then i have two executors blocking as the top-level defined build-node is not stopped.
在顶层设置 agent none
并按步骤配置代理.那么第一个节点上不存在 git checkout.
Setting agent none
on top-level and configuring the agents per step. then the git checkout is not present on the first node.
编辑 1
我按照您的建议重新配置了我的管道,目前看起来像这样:
i reconfigured my pipeline following you advice, it currently looks like this:
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'
}
}
}
}
此构建将失败,因为工作区不会在步骤之间转移,因为它们不在同一个执行程序上运行.
this build will fail because the workspace does not carry over between steps as they dont run on the same executor.
编辑 2
显然,有时这些步骤会在同一个执行程序上运行,有时则不会.(我们在 mesos/dcos 集群上按需生成构建从属服务器,因此更改执行器中间构建将是一个问题)
apparently sometimes the steps run on the same executor and sometimes don't. (we spawn build slaves on our mesos/dcos cluster on demand, so changing the executor mid build would be a problem)
只要代理定义中的标签不改变,我希望 jenkins 只使用当前执行程序运行.
I expected jenkins to just run with the current executor as long as the label in the agent definition does not change.
推荐答案
参见 最佳实践 7:不要:在节点块中使用输入.在声明式管道中,节点选择是通过 agent
指令完成的.
See best practice 7: Don’t: Use input within a node block. In a declarative pipeline, the node selection is done through the agent
directive.
此处文档描述了如何定义 none
用于管道,然后使用阶段级 agent
指令在所需节点上运行阶段.我也尝试了相反的方法(在某个节点上定义一个全局代理,然后在舞台级别为输入定义 none
),但这不起作用.如果流水线分配了一个从属设备,则您不能在一个或多个特定阶段释放该从属设备.
The documentation here describes how you can define none
for the pipline and then use a stage-level agent
directive to run the stages on the required nodes. I tried the opposite too (define a global agent on some node and then define none
on stage-level for the input), but that doesn't work. If the pipeline allocated a slave, you can't release the slave for one or more specific stages.
这是我们的管道的结构:
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"的构建从属设备上执行,但输入阶段在主设备上运行.
Generally, the build stages execute on a build slave labeled "yona", but the input stage runs on the master.
这篇关于如何在声明式管道中等待用户输入而不阻塞重量级执行器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!