将环境变量从Jenkins文件传递到以管道为代码的共享库

时间:2020-01-29 07:58:27

标签: jenkins jenkins-pipeline shared-libraries

我正在尝试使用一个公共共享库,该库具有实际的管道作为代码,在 vars / demo.groovy

下类似
def call(Map pipelineParams) {

pipeline {
  agent {
    docker { image 'centos:latest' }
  }

    stages {
        stage("Env Variables") {
            steps {
                sh "printenv"
                //echo ${SERVICE_NAME}
            }
        }

        stage("test") {
            steps {
                sh "printenv"
            }
    }
  }
    }   
}

我将这样从我的 Jenkinsfile 访问共享库。

library identifier: 'mylibraryname@master', 
    //'master' refers to a valid git-ref
    //'mylibraryname' can be any name
    retriever: modernSCM([
      $class: 'GitSCMSource',
      //credentialsId: 'your-credentials-id',
      remote: 'GIT URL'
    ])

demo()

它正在按预期工作,但我想发送一个额外的环境变量或覆盖我的 Jenkinsfile 中的现有变量,而无需更改将我的管道作为代码的共享库。您能如何帮助我?

我尝试给出如下变量:

demo {
    service = 'test'
    var1 = 'value'
}

并尝试让他们使用这种方式:

def call(Map pipelineParams) {

pipeline {
  agent {
    docker { image 'centos:latest' }
  }
    stages {
        stage("Env Variables") {
            steps {
                sh "printenv"
                echo "pipelineParams.service"
            }
        }

        stage("test") {
            steps {
                sh ' echo "hello pipelineParams.service '
            }
    }
  }
    }   
}

但是出现以下错误:

[Pipeline] End of Pipeline

hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: demo.call() is applicable for argument types: (org.jenkinsci.plugins.workflow.cps.CpsClosure2) values: [org.jenkinsci.plugins.workflow.cps.CpsClosure2@cad5c94]

Possible solutions: call(java.util.Map), wait(), any(), wait(long), main([Ljava.lang.String;), each(groovy.lang.Closure)

    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:58)

    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:64)

    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:54)

    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)

    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)

    at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:160)

    at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:23)

    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:157)

    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:142)

    at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:158)

1 个答案:

答案 0 :(得分:2)

此签名是此处定义的地图

def call(Map pipelineParams)

因此您需要使用地图。 (https://www.baeldung.com/groovy-maps) 看起来像是:

demo([
    service: 'test',
    var1: 'value'
])

您的echo语句也不完全正确,应该是:

echo(pipelineParams.service)

完全不需要使用GString或字符串,因为它是一个常规变量。

注意:我在示例中使用()。严格来说,您不需要它们。我只是喜欢这样编码,所以很明显这些是方法参数。

您也可以只创建环境变量。尽管我可能不建议这样做,但会更像您当前的计划那样做。

withEnv([SERVICE='test', VAR1='value]) {
    demo([:]) // I put an empty map here, if you did this you would change your call method to not have the map though
}

上面的这种方式可确保env var仅在关闭结束(最后一个大括号)之前有效

另一种方法,但这只是设置它们,它们将在全局范围内以及其余的运行中存在。不太好。

env.SERVICE = 'test'
env.VAR1 = 'value'

demo([:])

无论哪种情况,在您的共享库中,您都需要检查:

echo env.SERVICE

尽管我认为最好还是以第一方式进行。接受地图参数并使用它们。 env var可能是全局变量,有时会导致问题,具体取决于您的跑步情况。