Passing Environment variables from Jenkins file to Shared Library which has the pipeline as code
Answer a question
I am trying to have one common shared library which has actual pipeline as code, something like this under 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.
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 . 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)
Answers
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:
demo([
service: 'test',
var1: 'value'
])
Your echo statement is also not quite right, it should be:
echo(pipelineParams.service)
There is no need to use a GString or a string at all because it is a groovy variable.
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. env vars can be global and cause issues sometimes depending on what your running.
更多推荐
所有评论(0)