问题描述
在使用Jenkins的声明式Pipeline时,有一个需求是希望在不同的阶段之间传递脚本生成的变量。用户想知道是否有一种优雅的方式来实现这个目标。
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
对于声明式Pipeline,可以使用文件来传递变量的值。以下是一个示例:
pipeline {
agent { label 'docker' }
stages {
stage('one') {
steps {
sh 'echo hotness > myfile.txt'
script {
// trim removes leading and trailing whitespace from the string
myVar = readFile('myfile.txt').trim()
}
echo "${myVar}" // 输出 'hotness'
}
}
stage('two') {
steps {
echo "${myVar}" // 输出 'hotness'
}
}
// 这个阶段由于 when 表达式被跳过,所以不会输出任何内容
stage('three') {
when {
expression { myVar != 'hotness' }
}
steps {
echo "three: ${myVar}"
}
}
}
}
在上面的示例中,我们使用sh
命令将变量的值写入文件myfile.txt
。然后,使用readFile
函数从文件中读取变量的值,并将其赋给myVar
变量。在后续的阶段中,我们可以使用${myVar}
来引用这个变量的值。
另外,你还可以使用writeFile
和readFile
函数直接将脚本的输出写入文件,并在后续的阶段中读取文件的内容。但需要注意的是,写入和读取文件的操作必须在同一个节点上进行,不能在不同的节点之间传递数据。
此外,你还可以使用archiveArtifact
函数将文件存档,并使用copyArtifact
函数检索文件(然后使用readFile
函数读取文件)。
最后,你可以参考StackOverflow上一个类似问题的答案,其中提供了一些其他的解决方案。
方案2
如果可能的话,建议使用Scripted Pipeline,它可以提供更简单的解决方案。以下是一个示例:
def myVar
stage('my-first-stage') {
myVar = sh(script: 'my-command', returnStdout: true)
}
stage('my-second-stage') {
sh("my-other-command --var='${myVar}'")
}
在这个示例中,我们首先定义了一个变量myVar
。然后,在第一个阶段中,我们使用sh
命令执行脚本,并将输出赋给myVar
变量。在第二个阶段中,我们可以使用${myVar}
来引用这个变量的值。
这种方法比声明式Pipeline更简单,可以更方便地传递变量的值。
请注意,上述解决方案已经在评论中提到过,但你对它们的优雅程度有所担忧。在Jenkins Pipeline中,我无法想到任何简化这些答案的方式,因此这些解决方案应该是目前最优雅的方法。