Search code examples
jenkinsjenkins-pipeline

How can I pass environment variables to Jenkins Pipeline Tools section


In Jenkins > Global Tool Configuration > JDK installation > I have added JDK7 and its name is oracle-7u80; Similarly under Maven installation, I have added Maven 3.5 install and named it mvn.

Now I am using the above two installs in the Pipeline script:

    pipeline {
    agent any
    tools {
        maven 'mvn'
        jdk 'oracle-7u80'
    }
    stages {
        stage('Example') {
            steps {
                
                }
            }
        }
    }

I do not want to hard code the jdk and Maven values in the Tools section in the pipeline. I want to pass these values via environment variables or properties so that I can manage them externally.

Is there a way to pass the values (mvn or oracle-7u80) that is defined to Maven and jdk in the tools using environment variables?

Like if I need to inject a value within Steps/Script section, in Jenkins pipeline, I can define globally in the environment variables or using Jenkins project Configure General Check mark Prepare an environment for the run Check mark Keep Jenkins environment variables I can provide the environment variable in the properties content with Properties File definition.

My intention is to get a format like this:

pipeline {
    agent any
    tools {
        maven '${MVN_VERSION}'
        jdk '${ORACLE_VERSION'}
    }
    stages {
        stage('Example') {
            steps {
            
                }
            }
        }
    }

Solution

  • Pipeline projects are often used with a Jenkinsfile (Pipeline script from SCM in the PipelineDefinition drop-down list) to bind a source code version and its build configuration to each other for reproducable builds.

    Injecting build tool versions from external before the build contradicts this idea.

    I'm also not sure whether this is even possible conceptually since (environment) variables' values from external are set in stages ... script which is a totally different declaration branch than tools. But hey, it's called declarative pipeline, not imperative, so order shouldn't matter ... in theory. I'll give it a try.

    For passing external values into internal variables in general see Pipeline: Nodes and Processes, sh: Shell Script and also the answer to the question How to access Shell variable value into Groovy pipeline script.

    Maven version injection try

    pipeline {
        agent any
        
        tools {
            maven "${MVN_VERSION}"
        }
        
        stages {
            stage('Try: Maven version injected') {
                steps {
                    script {
                        env.MVN_VERSION = sh script: 'echo "Maven 3.8.1"', returnStdout: true
                    }
                    echo "${MVN_VERSION}"                
                }
            }
        }
    }
    

    As expected:

    [Pipeline] stage
    [Pipeline] { (Declarative: Tool Install)
    [Pipeline] }
    [Pipeline] // stage
    [Pipeline] }
    [Pipeline] // node
    [Pipeline] End of Pipeline
    groovy.lang.MissingPropertyException: No such property: MVN_VERSION for class: groovy.lang.Binding
    ...
    

    Another idea that came into my mind is to make this project parameterized with two parameters (e.g. MVN_GLOBAL_TOOL_NAME, JDK_GLOBAL_TOOL_NAME) via Choice parameter s, for instance, and this works:

    pipeline {
        agent any
        
        tools {
            maven "${MVN_GLOBAL_TOOL_NAME}" // coming from parameterized project's build parameter
        }
        
        stages {
            stage('Maven tool as build parameter') {
                steps {
                    echo "MVN_GLOBAL_TOOL_NAME=${MVN_GLOBAL_TOOL_NAME}"                
                }
            }
        }
    }
    

    Console Outpout

    [Pipeline] stage
    [Pipeline] { (Declarative: Tool Install)
    [Pipeline] tool
    [Pipeline] envVarsForTool
    [Pipeline] }
    [Pipeline] // stage
    [Pipeline] withEnv
    [Pipeline] {
    [Pipeline] stage
    [Pipeline] { (Maven version as build parameter)
    [Pipeline] tool
    [Pipeline] envVarsForTool
    [Pipeline] withEnv
    [Pipeline] {
    [Pipeline] script
    [Pipeline] {
    [Pipeline] echo
    MVN_GLOBAL_TOOL_NAME=Maven 3.8.1
    [Pipeline] }
    [Pipeline] // withEnv
    [Pipeline] }
    [Pipeline] // stage
    [Pipeline] }
    [Pipeline] // withEnv
    [Pipeline] }
    [Pipeline] // node
    [Pipeline] End of Pipeline
    Finished: SUCCESS
    

    See also ${JENKINS_URL}/job/${JOB_NAME}/api/:

    Perform a build

    If the build has parameters, post to this URL [Link note: ${JENKINS_URL}/job/${JOB_NAME}/buildWithParameters] and provide the parameters as form data.

    See also: ${JENKINS_URL}/env-vars.html/.