Jenkins:在全局函数的主体中获取环境变量
Jenkins: get environment variables in the body of a global function
我在 PublishGitHub.groovy 上有一个共享的全局函数,如下所示:
#!/usr/bin/env groovy
def call(body)
{
def config = [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = config
echo "\u001B[32mINFO: Publishing...\u001B[m"
body()
echo "\u001B[32mINFO: End Publish...\u001B[m"
}
还有我的 JenkinsFile 上的代码:
environment {
VERSION = "v1.3.${env.BUILD_NUMBER}"
}
stages {
stage ('Publish WebAPI'){
steps{
echo "\u001B[32mINFO: Start Publish...\u001B[m"
PublishGitHub{
echo "This is a body with version: ${env.VERSION}"
}
}
}
}
这是我的输出:
[Pipeline] echo
INFO: Start Publish...
[Pipeline] echo
INFO: Publishing...
[Pipeline] }
并遵循下一个错误:
java.lang.NullPointerException: Cannot get property 'VERSION' on null
object
因为在body里面我没有权限访问环境变量?
为了使您在 Jenkinsfile 中定义的环境变量在共享库代码中可用,您必须在调用共享库方法时传递 this 参数.
例如(以下是完整管道文件的部分摘录):
// JENKINS-42730
@Library('pipeline-shared-library')_
import org.blah.MySharedLibraryClass
// END JENKINS_42730
pipeline {
agent { any }
environment {
FOO = (new MySharedLibraryClass(config, this)).myMethod("StringVar1", "StringVar2")
}
}
我的共享库:
package org.blah
import groovy.text.SimpleTemplateEngine
public class MySharedLibraryClass implements Serializable {
def engine = new SimpleTemplateEngine()
def config
def steps
def ArtifactoryHelper(config, steps) {
this.config = config
this.steps = steps
}
def log(msg){
//Allows me to print to Jenkins console
steps.println(msg)
}
def myMethod(var1, var2) {
....
}
我上面提到的这个参数映射到共享库代码中的步骤。然后您应该能够在您的共享库代码中解析 "VERSION=${steps.env.VERSION}"
。
另请参阅此 。
备注:
pipeline-shared-library
是我在 Manage Jenkins > Configure System 中给库的 ID
您的共享库代码 运行 在工作流 CPS 上下文之外,这就是为什么您传递给 vars 脚本的闭包无法识别 env
属性。您可以通过传递对工作流脚本的引用来解决此问题。如果你这样调用你的函数
PublishGitHub(this) {
echo "This is a body with version: ${env.VERSION}"
}
然后您对 vars/PublishGitHub.groovy
脚本进行了小的修改,例如:
#!/usr/bin/env groovy
def call(config, body) {
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = config
echo "\u001B[32mINFO: Publishing...\u001B[m"
body()
echo "\u001B[32mINFO: End Publish...\u001B[m"
}
然后您将 运行 您的管道成功:
[Pipeline] {
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Publish WebAPI)
[Pipeline] echo
[32mINFO: Start Publish...[m
[Pipeline] echo
[32mINFO: Publishing...[m
[Pipeline] echo
This is a body with version: v1.3.537
[Pipeline] echo
[32mINFO: End Publish...[m
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
如果你想限制共享库的范围,你总是可以简单地传递 env
而不是 this
并将 vars/PublishGitHub.groovy
更改为这样的东西:
#!/usr/bin/env groovy
def call(env, body) {
def config = [
env: env
]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = config
echo "\u001B[32mINFO: Publishing...\u001B[m"
body()
echo "\u001B[32mINFO: End Publish...\u001B[m"
}
在这种情况下,您只允许共享库访问环境变量。
Szymon 的回答有效。我添加了 "p.env = env"
def toParam(final Closure body) {
final def p = [:]
p.env = env
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = p
body()
return p
}
我在 PublishGitHub.groovy 上有一个共享的全局函数,如下所示:
#!/usr/bin/env groovy
def call(body)
{
def config = [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = config
echo "\u001B[32mINFO: Publishing...\u001B[m"
body()
echo "\u001B[32mINFO: End Publish...\u001B[m"
}
还有我的 JenkinsFile 上的代码:
environment {
VERSION = "v1.3.${env.BUILD_NUMBER}"
}
stages {
stage ('Publish WebAPI'){
steps{
echo "\u001B[32mINFO: Start Publish...\u001B[m"
PublishGitHub{
echo "This is a body with version: ${env.VERSION}"
}
}
}
}
这是我的输出:
[Pipeline] echo
INFO: Start Publish...
[Pipeline] echo
INFO: Publishing...
[Pipeline] }
并遵循下一个错误:
java.lang.NullPointerException: Cannot get property 'VERSION' on null object
因为在body里面我没有权限访问环境变量?
为了使您在 Jenkinsfile 中定义的环境变量在共享库代码中可用,您必须在调用共享库方法时传递 this 参数.
例如(以下是完整管道文件的部分摘录):
// JENKINS-42730
@Library('pipeline-shared-library')_
import org.blah.MySharedLibraryClass
// END JENKINS_42730
pipeline {
agent { any }
environment {
FOO = (new MySharedLibraryClass(config, this)).myMethod("StringVar1", "StringVar2")
}
}
我的共享库:
package org.blah
import groovy.text.SimpleTemplateEngine
public class MySharedLibraryClass implements Serializable {
def engine = new SimpleTemplateEngine()
def config
def steps
def ArtifactoryHelper(config, steps) {
this.config = config
this.steps = steps
}
def log(msg){
//Allows me to print to Jenkins console
steps.println(msg)
}
def myMethod(var1, var2) {
....
}
我上面提到的这个参数映射到共享库代码中的步骤。然后您应该能够在您的共享库代码中解析 "VERSION=${steps.env.VERSION}"
。
另请参阅此
备注:
pipeline-shared-library
是我在 Manage Jenkins > Configure System 中给库的 ID
您的共享库代码 运行 在工作流 CPS 上下文之外,这就是为什么您传递给 vars 脚本的闭包无法识别 env
属性。您可以通过传递对工作流脚本的引用来解决此问题。如果你这样调用你的函数
PublishGitHub(this) {
echo "This is a body with version: ${env.VERSION}"
}
然后您对 vars/PublishGitHub.groovy
脚本进行了小的修改,例如:
#!/usr/bin/env groovy
def call(config, body) {
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = config
echo "\u001B[32mINFO: Publishing...\u001B[m"
body()
echo "\u001B[32mINFO: End Publish...\u001B[m"
}
然后您将 运行 您的管道成功:
[Pipeline] {
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Publish WebAPI)
[Pipeline] echo
[32mINFO: Start Publish...[m
[Pipeline] echo
[32mINFO: Publishing...[m
[Pipeline] echo
This is a body with version: v1.3.537
[Pipeline] echo
[32mINFO: End Publish...[m
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
如果你想限制共享库的范围,你总是可以简单地传递 env
而不是 this
并将 vars/PublishGitHub.groovy
更改为这样的东西:
#!/usr/bin/env groovy
def call(env, body) {
def config = [
env: env
]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = config
echo "\u001B[32mINFO: Publishing...\u001B[m"
body()
echo "\u001B[32mINFO: End Publish...\u001B[m"
}
在这种情况下,您只允许共享库访问环境变量。
Szymon 的回答有效。我添加了 "p.env = env"
def toParam(final Closure body) {
final def p = [:]
p.env = env
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = p
body()
return p
}