首页 > 解决方案 > 依赖于 Jenkins 构建布尔参数的表达式在管道中不起作用

问题描述

我继承了一些 Jenkins 管道并尝试改进它。Jenkins 和 groovy 对我来说是相当新鲜的话题,所以很可能我做错了什么。我在用着Jenkins ver. 2.121.3

主要目的是添加构建参数以在构建期间进行一些额外的清理。因此,我在作业配置中添加CLEAN_FIRST了布尔类型和默认值false的参数,并在管道中执行了类似的操作:

// CLEAN_FIRST = false
// def prefix = CLEAN_FIRST ? "" : "REM"

pipeline {
    agent none
    stages {
        stage('Some step') {
            steps {
                script {
                    node('master') {
                        cleanWs()
                        try {
                            def prefix = CLEAN_FIRST ? "" : "REM"
                            echo "CLEAN_FIRST=$CLEAN_FIRST prefix=$prefix"
                            bat (label: 'build third party',
                                script: """
                                $prefix call cleanSomthing.bat
                                call doOtherStuff.bat
                                """
                        } finally {
                            echo "some stuff"
                        }
                    } // node
                } // script 
            } // steps
        } // stage
    } // stages
} // pipeline

现在这不能按预期工作。不添加“REM”前缀。

回声打印:

CLEAN_FIRST=false prefix=

以及我希望避免的bat调用cleanSomthing.bat(以节省构建时间)。

我试图使prefix全球化,但结果相同。

这很可能是由一些评估顺序或范围问题引起的,但我不能指望它。

有人可以告诉我为什么它不起作用吗?如何解决?


回答了自己的问题。这个问题在某些版本的 Jenkins 上修复了吗?

标签: jenkinsjenkins-pipelinejenkins-groovy

解决方案


好的,我找到了问题的根源。这有点好笑。

运行此管道时(在 Mac 机器上测试,因为它有空作业队列):

pipeline {
    agent none
    stages {
        stage('Some step') {
            steps {
                script {
                    node('Mac') {
                        cleanWs()
                        try {
                            def logic = true
                            def prefix = CLEAN_FIRST ? "Ole" : "REM"
                            def typeLogic = logic.getClass()
                            def typeParam = CLEAN_FIRST.getClass()

                            echo "typeLogic=$typeLogic typeParam=$typeParam"
                            echo "CLEAN_FIRST=$CLEAN_FIRST prefix=$prefix"
                            sh (script: """
                            echo prefix=$prefix
                            """)
                        } finally {
                            echo "some stuff"
                        }
                    } // node
                } // script 
            } // steps
        } // stage
    } // stages
} // pipeline

我得到了这个结果:

Running in Durability level: MAX_SURVIVABILITY
[Pipeline] stage
[Pipeline] { (Some step)
[Pipeline] script
[Pipeline] {
[Pipeline] node
Running on master in /Users/builder/jenkins/workspace/EIbuild_MacOS
[Pipeline] {
[Pipeline] cleanWs
[WS-CLEANUP] Deleting project workspace...[WS-CLEANUP] done
[Pipeline] echo
typeLogic=class java.lang.Boolean typeParam=class java.lang.String
[Pipeline] echo
CLEAN_FIRST=false prefix=Ole
[Pipeline] sh
[EIbuild_MacOS] Running shell script
+ echo prefix=Ole
prefix=Ole
[Pipeline] echo
some stuff
[Pipeline] }
[Pipeline] // node
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] End of Pipeline
Finished: SUCCESS

所以现在source问题就很明显了。Jenkins 在配置中承诺了 type 变量Boolean,但实际上提供了String带有值的类型,"true"或者在用作条件时"false"总是被评估,true因为这两个值都不是空字符串:)。


推荐阅读