我在SCM中有一个带有脚本Jenkinsfile的多分支管道项目。我想通过共享的全局函数在管道中设置环境变量。我共享的全局函数如下所示:
#!/usr/bin/groovy
def call(String envName = 'staging') {
def json = libraryResource 'env-config.yaml'
def config = readYaml text: json
def envObj = config.environments.find{it.name == envName}
environment {
PROJECT = ${envObj.project}
ARTIFACTS_REPOSITORY = ${envObj.artifacts_repository}
DOCKER_REGISTRY_PREFIX = ${envObj.docker_registry_prefix}
}
println "${envObj}"
}
但是在我的Jenkinsfile中,我看不到这些设置:
timestamps {
withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'xxx', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) {
node('klm') {
try {
def revisionTag
loadEnvConfig('staging')
println "project=${env.PROJECT}, repo=${env.ARTIFACTS_REPOSITORY}"
...
env.PROJECT
并且env.ARTIFACTS_REPOSITORY
均为null。如果我envObj
从函数返回并在管道中打印属性,则可以看到它们。是否可以通过我的函数设置环境变量?
编辑:我刚刚意识到我无法在多分支管道的Jenkinsfile中设置任何环境变量。例如,这两种模式都不起作用
timestamps {
withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'xxx', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) {
node('klm') {
try {
environment {
FOO = "bar"
}
println "project=${env.FOO}"
...
timestamps {
withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'xxx', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) {
node('klm') {
try {
withEnv(["FOO=BAR"]) {
println "project=${env.FOO}"
...
我不确定是什么environment
,为什么它不会让您失望。PROJECT = ${envObj.project}
是无效的Groovy,因此不会执行该块。似乎您正在尝试将environment
指令用于声明性管道,但是您正在使用脚本化管道。由于共享库和声明性管道的限制,以下选项仅对脚本化管道有效。
在当前代码中,您不会修改任何全局脚本变量或返回要在其他步骤中使用的值,因此它们不会起作用。根据要提供给消费者的API,您有几种不同的方法。
第一种选择是只修改env
全局变量:
env.PROJECT = envObj.project
env.ARTIFACTS_REPOSITORY = envObj.artifacts_repository
env.DOCKER_REGISTRY_PREFIX = envObj.docker_registry_prefix
这些将修改env
脚本中其他任何地方都可用的全局状态(除非它们被覆盖或删除)。
另一种选择是使用现有withEnv
步骤编写方法,并允许消费者提供Closure
主体。这里是我从改名功能的例子loadEnvConfig
来withEnvConfig
:
def call(String envName = 'staging', Closure body) {
// Previous code...
withEnv([
"PROJECT=${envObj.project}",
"ARTIFACTS_REPOSITORY=${envObj.artifacts_repository}",
"DOCKER_REGISTRY_PREFIX=${envObj.docker_registry_prefix}",
]) {
body()
}
}
Jenkinsfile
withEnvConfig('staging') {
println "In block project=${env.PROJECT}, repo=${env.ARTIFACTS_REPOSITORY}"
}
println "Out of block project=${env.PROJECT}, repo=${env.ARTIFACTS_REPOSITORY}"
在主体内部,将它们设置为的值withEnv
。在块外,它们被重置。
我更喜欢这种模式来修改全局状态。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句