Jenkinsfile-脚本管道语法中的条件阶段执行
我们正在为我们的Jenkinsfile-脚本管道语法中的条件阶段执行,jenkins,groovy,jenkins-pipeline,Jenkins,Groovy,Jenkins Pipeline,我们正在为我们的Jenkinsfile使用脚本管道语法,它定义了许多构建和部署代码的阶段。我们有一个用例,如果我正在进行完整构建,我希望运行所有阶段,但如果我需要执行一些AWS路由,则只运行一个特定阶段。我知道我可以使用if()跳过一个阶段或运行一个阶段。问题是我不想将if条件应用到我的Jenkins文件中的每个阶段 在新的声明性管道语法中,使用stage..when选项可以轻松实现这一点。我们的基础设施中使用了大量定制Groovy helper函数,因此目前我不可能从脚本管道语法切换到新的声明
Jenkinsfile
使用脚本管道语法,它定义了许多构建和部署代码的阶段。我们有一个用例,如果我正在进行完整构建,我希望运行所有阶段,但如果我需要执行一些AWS路由,则只运行一个特定阶段。我知道我可以使用if()
跳过一个阶段或运行一个阶段。问题是我不想将if
条件应用到我的Jenkins文件中的每个阶段
在新的声明性管道语法中,使用stage..when
选项可以轻松实现这一点。我们的基础设施中使用了大量定制Groovy helper函数,因此目前我不可能从脚本管道语法切换到新的声明性管道语法。我在现有的Jenkinsfile
上所做的事情与此类似
原始詹金斯档案
stage('Checkout Code') {}
stage('Build') {}
parallel(
stage('Sonar Analysis') {}
stage('CLM Analysis') {}
stage('Security Analysis') {}
)
stage('Build Docker Image') {}
...
...
stage('QA Deploy') {}
stage('QA Routing') {}
...
...
stage('Prod Deploy') {}
stage('Prod Routing') {}
改为
if (fullDeploy){
stage('Full Build') {
stage('Checkout Code') {}
stage('Build') {}
parallel(
stage('Sonar Analysis') {}
stage('CLM Analysis') {}
stage('Security Analysis') {}
)
stage('Build Docker Image') {}
...
...
stage('QA Deploy') {}
stage('QA Routing') {}
...
...
stage('Prod Deploy') {}
stage('Prod Routing') {}
}
}
if (routeOnly){
stage('Prod Routing') {}
}
这让我感觉有点不舒服,我在Jenkins文档中找不到任何可以提供这种方法的东西
有没有人能找到更好的方法来合并它?我不使用脚本化管道,但我很确定这就是您的方法(将条件阶段包含在if
中)
如果您希望它的行为更像声明性的,您可以将If
语句放在每个阶段中。这样,阶段仍然可以可视化。当他们实际上没有做任何事情时,这可能是可取的,也可能不是可取的
我认为切换到声明性将是在blue ocean UI中以不同方式显示跳过的阶段的唯一方法(由于when
子句,它们在被跳过时看起来不同),但您当前的解决方案实际上拥有最小的代码。这对我来说似乎并不令人讨厌,但这类事情可能是主观的 我也不喜欢在我的stage{}中有一个冗余的if{}块。
我通过如下覆盖舞台解决了这个问题
def stage(name, execute, block) {
return stage(name, execute ? block : {echo "skipped stage $name"})
}
现在,您可以如下禁用一个阶段
stage('Full Build', false) {
...
}
更新
您还可以使用以下def标记跳过的阶段
import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
def stage(name, execute, block) {
return stage(name, execute ? block : {
echo "skipped stage $name"
Utils.markStageSkippedForConditional(STAGE_NAME)
})
}
根据上的评论,当
支持脚本化管道时,听起来不像是添加了。作为一种潜在的解决方法,有一个共享库实现了脚本化管道的when
语句:我将使用环境变量跳过阶段
stage("Release"){
steps{
// Release procedure
}
when {
allOf{
branch 'release'
not{
environment name: 'JENKINS_SKIP_RELEASE', value: 'TRUE'
}
}
}
}
在我的特定工作方式中,整个管道是一个变量,因此我调整它以检查特定变量
def call(body) {
// Execute the body and get parameters back.
def params = [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = params
body()
if (params.skip_release){
env.JENKINS_SKIP_RELEASE = 'TRUE'
}
[...]
然后,我所有的Jenkinsfile
看起来都像一堆参数
@Library('shared') _
myGeneralizedPipeline {
skip_release = true
//Other parameters comes in this body
}
我认为在脚本化管道中没有跳过阶段的好方法-请参阅。谢谢@mkobit。知道这一点很有帮助。谢谢@burnettk。你是对的。这是非常主观的。我会把这个问题留一点时间,以防有人过来,给我一个很好的和优雅的方式来做这件事。如果不是,我会接受你的回答。这个答案是不正确的,有一种方法可以在脚本管道中实现。一旦你找到了好的来源,这是很容易的:谢谢!真是个好主意!不是为我工作的。。。我在阶段(“Verify${stageToDisplay}”,overallBuildRun)上获得了“java.lang.IllegalArgumentException:预期命名参数,但获得了[Verify Pre-prod,true]”的并行代码execution@DeanChen你有没有用同样的方法来编写一个平行的(阶段)脚本?我找不到it@Marcello取消销售我没有为此使用并行。嗨,我使用脚本化阶段来拥有动态并行阶段。因为脚本化的时候是不可能的,但我想看到所有可能的阶段,想看到执行与否。提到的Utils.markStageSkippedForConditional(STAGE_NAME)仅在概述中工作正常,跳过的阶段现在为空,但在蓝色海洋视图中,跳过的阶段也有一个复选标记。有人也有这个吗?