简体   繁体   English

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

[英]Passing Environment variables from Jenkins file to Shared Library which has the pipeline as code

I am trying to have one common shared library which has actual pipeline as code, something like this under vars/demo.groovy我正在尝试拥有一个通用共享库,它具有实际的管道作为代码,类似于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"
            }
    }
  }
    }   
}

And I will be accessing the shared Library from my Jenkinsfile like this.我将像这样从我的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()

It is working as expected but I want to send an extra environment variable or override existing variables from my Jenkinsfile without making changes to shared library which has my pipeline as code .它按预期工作,但我想从我的Jenkinsfile发送一个额外的环境变量或覆盖现有变量,而无需更改将我的管道作为代码的共享库。 can you help me with how could this be achieved?你能帮我解决这个问题吗?

I have tried giving the variables as below:我试过给出如下变量:

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

And tried them accessing this way:并尝试以这种方式访问​​:

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 '
            }
    }
  }
    }   
}

But getting the following error:但收到以下错误:

[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)

The signature of this is a map as defined here这个签名是一个定义在这里的地图

def call(Map pipelineParams)

So you need to use a map.所以你需要使用地图。 ( https://www.baeldung.com/groovy-maps ) What this would look like is: ( https://www.baeldung.com/groovy-maps ) 这看起来像:

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

Your echo statement is also not quite right, it should be:你的 echo 语句也不太对,应该是:

echo(pipelineParams.service)

There is no need to use a GString or a string at all because it is a groovy variable.根本不需要使用 GString 或字符串,因为它是一个 groovy 变量。

Note: I use () in my examples.注意:我在示例中使用 ()。 Strictly speaking you don't need them.严格来说,你不需要它们。 I just prefer to code this way so its clear these are method arguments.我只是更喜欢以这种方式编码,因此很明显这些是方法参数。

You could also just create env vars.您也可以只创建环境变量。 Though I probably don't recommend it and would do it more like the way you are currently planning.虽然我可能不推荐它,并且会更像您目前计划的方式来做。

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
}

This way above ensures the env vars only live until the end of the closure (the last } brace)上面的这种方式确保环境变量只存在到闭包结束(最后一个 } 大括号)

Another way, but this just sets them and they will exist globally and for the rest of the run.另一种方式,但这只是设置它们,它们将在全球范围内和运行的其余部分存在。 Not great.不是很好。

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

demo([:])

in either case, in your shared lib you would check:无论哪种情况,在您的共享库中,您都会检查:

echo env.SERVICE

Again though I think its better the first way your doing it.再一次,虽然我认为你这样做的第一种方式更好。 Accepting a map argument and using those.接受一个 map 参数并使用它们。 env vars can be global and cause issues sometimes depending on what your running. env vars 可能是全局的,有时会导致问题,具体取决于您的运行情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM