Jenkinsfile 不会更新变量的值

Jenkinsfile won't update variable's value

我正在尝试在 switch 语句上设置一个变量。 我创建了一个简单的函数来执行此操作,但它实际上不会更新值。这是我创建的函数:

def VAR1 = 'this is not the real value';

stage('Set Variables') {
    steps {
        script{
            SetVariables()
        }
    }
}

def SetVariables() {
    sh 'echo $BRANCH_NAME'
    switch(BRANCH_NAME){
        case 'BranchA':
            sh 'echo We are in the right branch'
            VAR1 = "This is the correct String"
            sh 'echo $VAR1 is the variable's value'
            break
    }
}

两个回声都在显示,但VAR1的值仍然是'this is not the real value'

如果我将这段代码移到 steps/script 块中,它就可以正常工作。

stage('Set Variables') {
            steps {
                script{
                    switch(BRANCH_NAME){
                        case 'BranchA':
                            sh 'echo We are in the right branch'
                            VAR1 = "This is the correct String"
                            sh 'echo $VAR1 is the variable's value'
                            break
                    }
                }
            }
        }

这段代码会随着我添加更多的变量和案例而扩展,我想将它存储在一个函数的底部,以保持代码的整洁和可读性。我在这里缺少什么阻止变量在函数中正确更新?

我认为这个问题与范围界定有关。

让我们了解一下行为。考虑到这条管道:

def MY_VAR = 'hello world'
fun()

pipeline {
    agent any

    stages {
        stage('Hello') {
            steps {
                script {
                    println("Pipeline Before: ${MY_VAR}")
                    fun()
                    println("Pipeline After : ${MY_VAR}")
                }
            }
        }
    }
}

def fun() {
    println("Fun before: ${MY_VAR}")
    VAR1 = 'hello world, in fun'
    println("Fun after : ${MY_VAR}")
}

如果我们 运行 这会出现以下错误:

groovy.lang.MissingPropertyException: No such property: MY_VAR for class: groovy.lang.Binding

让我们删除第二行中的 fun() 调用。我们得到以下输出

Pipeline Before: hello world

groovy.lang.MissingPropertyException: No such property: MY_VAR for class: groovy.lang.Binding

让我们从函数中删除第一个 println("Fun before: ${MY_VAR}")。我们得到:

Pipeline Before: hello world
[Pipeline] echo
Fun after : hello world, in fun
[Pipeline] echo
Pipeline After : hello world

我们可以看到这个值没有改变。为了解决这些问题,我们可以使用将我们的变量附加到 env 对象,如 env.MY_VAR

管道将如下所示

env.MY_VAR = 'hello world'
fun()

pipeline {
    agent any

    stages {
        stage('Hello') {
            steps {
                script {
                    println("Pipeline Before: ${env.MY_VAR}")
                    fun()
                    println("Pipeline After : ${env.MY_VAR}")
                }
            }
        }
    }
}

def fun() {
    println("Fun before: ${env.MY_VAR}")
    env.VAR1 = 'hello world, in fun'
    println("Fun after : ${env.MY_VAR}")
}

我们将得到:

[Pipeline] echo
Fun before: hello world
[Pipeline] echo
Fun after : hello world, in fun
[Pipeline] echo
Pipeline Before: hello world, in fun
[Pipeline] echo
Fun before: hello world, in fun
[Pipeline] echo
Fun after : hello world, in fun
[Pipeline] echo
Pipeline After : hello world, in fun

这是期望的输出。你可以争论 env 对象的使用,也许你可以参数化你的函数。我会这样做,因为如果我需要 bash/powershell/etc 脚本中的变量,我可以通过环境变量访问它。

Groovy 的一个怪癖是,如果你想要一个全局的,你必须在没有 def 的情况下定义它:

VAR1 = 'this is not the real value';
// the rest unchanged

我相信你的代码会按预期工作。