我的项目具有许多其他项目的许多公共变量,因此我使用Jenkins共享库并创建了一个vars/my_vars.groovy
文件,在其中定义了变量并返回了它们的Map:
class my_vars {
static Map varMap = [:]
static def loadVars (Map config) {
varMap.var1 = "val1"
varMap.var2 = "val2"
// Many more variables ...
return varMap
}
}
我将共享库加载到我的Jenkinsfile中,并在 environment 项目符号中调用该函数,因为我希望这些变量成为环境变量。
Jenkinsfile:
pipeline {
environment {
// initialize common vars
common_vars = my_vars.loadVars()
} // environment
stages {
stage('Some Stage') {
// ...
}
}
post {
always {
script {
// Print environment variables
sh "env"
} // script
} // always
} // post
} // pipeline
问题是环境项目符号有KEY=VALUE
对,因此我的common_vars
映射像字符串值一样加载(我可以在sh "env"
上看到它)。
...
vars=[var1:val1, var2:val2]
...
将这些值声明为环境变量的正确方法是什么? 我的目标是:
...
var1=val1
var2=val2
...
答案 0 :(得分:2)
Pipeline的环境变量仅存储字符串值。因此,当您将映射分配给env.common_vars
变量时,它会存储map.toString()
个等效项。
如果要将键值从映射重写为环境变量,则可以迭代变量映射并将每个k
-v
对分配给类似env."$k" = v
的对象。您可以通过在environment
块内调用一个类方法来做到这一点-这样,无论管道从哪个阶段重新启动,您都可以确保分配了环境变量。考虑以下示例:
class MyVars {
private Map config = [
var1: "val1",
var2: "val2"
]
String initializeEnvironmentVariables(final Script script) {
config.each { k,v ->
script.env."$k" = v
}
return "Initialization of env variables completed!"
}
}
pipeline {
agent any
environment {
INITIALIZE_ENV_VARIABLES_FROM_MAP = "${new MyVars().initializeEnvironmentVariables(this)}"
}
stages {
stage("Some stage") {
steps {
echo "env.var1 = ${env.var1}"
}
}
}
post {
always {
script {
sh 'printenv | grep "var[0-9]\\+"'
}
}
}
}
在此示例中,我们使用MyVars
类存储一些全局配置映射(它可以是共享库的一部分,为简单起见,这里是Jenkinsfile的一部分)。我们使用INITIALIZE_ENV_VARIABLES_FROM_MAP
环境变量分配来调用MyVars.initializeEnvironmentVariables(this)
方法,该方法可以从env
参数访问script
。从environment
块内部调用此方法有一个明显的好处-即使从任何阶段重新启动管道,它也可以确保环境变量将被初始化。
这是该示例管道的输出:
Running on Jenkins in /home/wololock/.jenkins/workspace/pipeline-env-map
[Pipeline] {
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Some stage)
[Pipeline] echo
env.var1 = val1
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Declarative: Post Actions)
[Pipeline] script
[Pipeline] {
[Pipeline] sh
+ grep 'var[0-9]\+'
+ printenv
var1=val1
var2=val2
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
如您所见,我们从封装在env.var1
类中的地图中设置了env.var2
和MyVars
。这两个变量都可以在管道步骤,脚本块中甚至在shell环境变量中访问。
答案 1 :(得分:1)
据我所知,在声明式管道中没有简单的方法(例如在environment指令中。相反,您可以做的是在声明式定义之外设置环境,如下所示:
my_vars.loadVars().each { key, value ->
env[key] = value
}
// Followed by your pipelines definition:
pipeline {
stages {
stage('Some Stage') {
// ...
}
}
// ...
} // pipeline
作为完整示例:
class my_vars {
static Map varMap = [:]
static def loadVars (Map config) {
varMap.var1 = "val1"
varMap.var2 = "val2"
// Many more variables ...
return varMap
}
}
my_vars.loadVars().each { key, value ->
env[key] = value
}
pipeline {
agent any
stages {
stage("Some stage") {
steps {
echo "env.var1 = ${env.var1}"
}
}
}
}
在构建时会输出以下内容:
Started by user xxx
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on yyy in /zzz
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Some stage)
[Pipeline] echo
env.var1 = val1
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
修改;如果您的课程(my_vars)位于共享库(MySharedLibrary)中:
library 'MySharedLibrary' // Will load vars/my_vars.groovy
my_vars.loadVars().each { key, value ->
env[key] = value
}
pipeline {
agent any
stages {
stage("Some stage") {
steps {
echo "env.var1 = ${env.var1}"
}
}
}
}