有没有办法在声明性 Jenkinsfile 中基于分支设置环境变量?
Is there a way to set environment variables based on branch in a Declarative Jenkinsfile?
我希望找到一种方法,通过加载基于分支的环境变量来删除声明式 Jenkinsfile 中的重复阶段。
目前我有类似的东西:
@Library("MySharedLibrary@v1") _
String tagBaseDev = "repo.org/myspace/image:dev"
String tagBaseTest = "repo.org/myspace/image:test"
String tagBaseProd = "repo.org/myspace/image:prod"
pipeline {
agent none
stages {
// Always Run This
stage ('Maven Build and Unit Tests') {
agent {label 'docker-slave'}
steps {
sharedLibraryBuild mavenGoals:'clean package', additionalProps:['ci.env':'']
stash 'artifacts'
}
}
// Dev Only
stage ('Build Dev Docker Image and Push') {
when {
branch 'dev'
}
agent {label 'docker-slave'}
steps {
unstash 'artifacts'
sharedLibraryDockerImageBuildPush tag:"$tagBaseDev"
}
}
// Test Only
stage ('Build Test Docker Image and Push') {
when {
branch 'test'
}
agent {label 'docker-slave'}
steps {
unstash 'artifacts'
sharedLibraryDockerImageBuildPush tag:"$tagBaseTest"
}
}
// Prod Only
stage ('Build Prod Docker Image and Push') {
when {
branch 'prod'
}
agent {label 'docker-slave'}
steps {
unstash 'artifacts'
sharedLibraryDockerImageBuildPush tag:"$tagBaseProd"
}
}
}
}
我希望能够将其缩减为一个阶段块,并根据分支动态加载所需的 $tagBaseXXX
。这只是一个例子,但我计划有四个或五个变量,每个环境都有不同的值。
我的想法是创建具有相应值的 EnvDev
、EnvTest
和 EnvProd
映射,然后创建一个 EnvMap
,这是一个关联分支名称的映射到环境地图。例如:
def EnvDev = [
url: "dev.com",
tag: "dev",
var: "Dev Var"
]
def EnvProd = [
url: "prod.com",
tag: "prod",
var: "prod Var"
]
def EnvMap = [
dev: EnvDev,
prod: EnvProd
]
然后我尝试创建一个如下所示的共享库调用:
def call(String branch, Map envMapping) {
Map use_me = envMapping.get("${branch}")
String url = use_me.get("URL")
echo ("${url}")
}
思路是通过Map根据分支拉取相应的环境贴图,然后根据需要使用变量。
所以我有这样的东西:
@Library("MySharedLibrary@v1") _
def EnvDev = [
url: "dev.com",
tag: "dev",
var: "Dev Var"
]
def EnvProd = [
url: "prod.com",
tag: "prod",
var: "prod Var"
]
def EnvMap = [
dev: EnvDev,
prod: EnvProd
]
pipeline {
agent {label 'docker-slave'}
stages {
stage ('Test Env Vars') {
steps {
echo "$env.GIT_BRANCH"
sharedLibrarySetupEnv branch: "$env.GIT_BRANCH", evnMapping: EnvMap
}
}
}
}
但我收到以下错误:
hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: setupEnv.call() is applicable for argument types: (java.util.LinkedHashMap) values: [[branch:dev, env_mapping:[dev:[url:dev.com, tag:dev, var:Dev Var], ...]]]
Possible solutions: call(java.lang.String, java.util.Map), wait(), any(), wait(long), main([Ljava.lang.String;), each(groovy.lang.Closure)
有没有更简单的方法来完成我想做的事情?
这是我第一次尝试编写共享库函数,所以我猜它可能只是一些我不熟悉的 Groovy syntax/concept。
谢谢!
您可以使用变量 BRANCH_NAME 并将其置于如下条件:-
if (env.BRANCH_NAME == master)
{
//set all the environment variable you need
} else {
//variable required if the condition doesn't match
}
您可以在条件中使用 REGEX。
你的函数签名是def call(String branch, Map envMapping)
,但你的调用是branch: xxx, env_mapping:xxx
。
改为sharedLibrarySetupEnv branch: "$env.GIT_BRANCH", envMapping: EnvMap
问题出在我尝试调用共享库函数的方式上。我以为我能够引用导致 Jenkinsfile/pipeline 将 LinkedHashMap
传递给共享库而不是两个单独的变量的变量名称。
有两种解决方法:
- 让共享库调用方法接收
Map<String, Object> parms
并在调用中引用变量 parms.varname
。
共享库:
def call(Map<String, Object> parms) {
echo "${parms.branch}"
Map use_this_map = parms.envMapping.get(branch)
}
詹金斯文件:
setupEnv branch: "$env.GIT_BRANCH", envMapping: EnvMap
- 不传递Jenkinsfile中的变量名,让Shared Library调用方法接受相应的变量。
共享库:
def call(String branch, Map<String, Map> envMapping) {
echo "${branch}"
Map use_this_map = envMapping.get(branch)
}
詹金斯文件:
setupEnv $env.GIT_BRANCH, EnvMap
我希望找到一种方法,通过加载基于分支的环境变量来删除声明式 Jenkinsfile 中的重复阶段。
目前我有类似的东西:
@Library("MySharedLibrary@v1") _
String tagBaseDev = "repo.org/myspace/image:dev"
String tagBaseTest = "repo.org/myspace/image:test"
String tagBaseProd = "repo.org/myspace/image:prod"
pipeline {
agent none
stages {
// Always Run This
stage ('Maven Build and Unit Tests') {
agent {label 'docker-slave'}
steps {
sharedLibraryBuild mavenGoals:'clean package', additionalProps:['ci.env':'']
stash 'artifacts'
}
}
// Dev Only
stage ('Build Dev Docker Image and Push') {
when {
branch 'dev'
}
agent {label 'docker-slave'}
steps {
unstash 'artifacts'
sharedLibraryDockerImageBuildPush tag:"$tagBaseDev"
}
}
// Test Only
stage ('Build Test Docker Image and Push') {
when {
branch 'test'
}
agent {label 'docker-slave'}
steps {
unstash 'artifacts'
sharedLibraryDockerImageBuildPush tag:"$tagBaseTest"
}
}
// Prod Only
stage ('Build Prod Docker Image and Push') {
when {
branch 'prod'
}
agent {label 'docker-slave'}
steps {
unstash 'artifacts'
sharedLibraryDockerImageBuildPush tag:"$tagBaseProd"
}
}
}
}
我希望能够将其缩减为一个阶段块,并根据分支动态加载所需的 $tagBaseXXX
。这只是一个例子,但我计划有四个或五个变量,每个环境都有不同的值。
我的想法是创建具有相应值的 EnvDev
、EnvTest
和 EnvProd
映射,然后创建一个 EnvMap
,这是一个关联分支名称的映射到环境地图。例如:
def EnvDev = [
url: "dev.com",
tag: "dev",
var: "Dev Var"
]
def EnvProd = [
url: "prod.com",
tag: "prod",
var: "prod Var"
]
def EnvMap = [
dev: EnvDev,
prod: EnvProd
]
然后我尝试创建一个如下所示的共享库调用:
def call(String branch, Map envMapping) {
Map use_me = envMapping.get("${branch}")
String url = use_me.get("URL")
echo ("${url}")
}
思路是通过Map根据分支拉取相应的环境贴图,然后根据需要使用变量。
所以我有这样的东西:
@Library("MySharedLibrary@v1") _
def EnvDev = [
url: "dev.com",
tag: "dev",
var: "Dev Var"
]
def EnvProd = [
url: "prod.com",
tag: "prod",
var: "prod Var"
]
def EnvMap = [
dev: EnvDev,
prod: EnvProd
]
pipeline {
agent {label 'docker-slave'}
stages {
stage ('Test Env Vars') {
steps {
echo "$env.GIT_BRANCH"
sharedLibrarySetupEnv branch: "$env.GIT_BRANCH", evnMapping: EnvMap
}
}
}
}
但我收到以下错误:
hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: setupEnv.call() is applicable for argument types: (java.util.LinkedHashMap) values: [[branch:dev, env_mapping:[dev:[url:dev.com, tag:dev, var:Dev Var], ...]]]
Possible solutions: call(java.lang.String, java.util.Map), wait(), any(), wait(long), main([Ljava.lang.String;), each(groovy.lang.Closure)
有没有更简单的方法来完成我想做的事情?
这是我第一次尝试编写共享库函数,所以我猜它可能只是一些我不熟悉的 Groovy syntax/concept。
谢谢!
您可以使用变量 BRANCH_NAME 并将其置于如下条件:-
if (env.BRANCH_NAME == master)
{
//set all the environment variable you need
} else {
//variable required if the condition doesn't match
}
您可以在条件中使用 REGEX。
你的函数签名是def call(String branch, Map envMapping)
,但你的调用是branch: xxx, env_mapping:xxx
。
改为sharedLibrarySetupEnv branch: "$env.GIT_BRANCH", envMapping: EnvMap
问题出在我尝试调用共享库函数的方式上。我以为我能够引用导致 Jenkinsfile/pipeline 将 LinkedHashMap
传递给共享库而不是两个单独的变量的变量名称。
有两种解决方法:
- 让共享库调用方法接收
Map<String, Object> parms
并在调用中引用变量parms.varname
。
共享库:
def call(Map<String, Object> parms) {
echo "${parms.branch}"
Map use_this_map = parms.envMapping.get(branch)
}
詹金斯文件:
setupEnv branch: "$env.GIT_BRANCH", envMapping: EnvMap
- 不传递Jenkinsfile中的变量名,让Shared Library调用方法接受相应的变量。
共享库:
def call(String branch, Map<String, Map> envMapping) {
echo "${branch}"
Map use_this_map = envMapping.get(branch)
}
詹金斯文件:
setupEnv $env.GIT_BRANCH, EnvMap