Search code examples
jenkinsjenkins-pipelinecontinuous-deliveryjenkins-2

How to configure a Jenkins 2 Pipeline so that Jenkinsfile uses a predefined variable


I have several projects that use a Jenkinsfile which is practically the same. The only difference is the git project that it has to checkout. This forces me to have one Jenkinsfile per project although they could share the same one:

node{
    def mvnHome = tool 'M3'
    def artifactId
    def pomVersion

    stage('Commit Stage'){
        echo 'Downloading from Git...'
        git branch: 'develop', credentialsId: 'xxx', url: 'https://bitbucket.org/xxx/yyy.git'
        echo 'Building project and generating Docker image...'
        sh "${mvnHome}/bin/mvn clean install docker:build -DskipTests"
    ...

Is there a way to preconfigure the git location as a variable during the job creation so I can reuse the same Jenkinsfile?

...
    stage('Commit Stage'){
        echo 'Downloading from Git...'
        git branch: 'develop', credentialsId: 'xxx', url: env.GIT_REPO_LOCATION
    ...

I know I can set it up this way:

This project is parameterized -> String Parameter -> GIT_REPO_LOCATION, default= http://xxxx, and access it with env.GIT_REPO_LOCATION.

The downside is that the user is promted to start the build with the default value or change it. I would need that it were transparent to he user. Is there a way to do it?


Solution

  • You can use the Pipeline Shared Groovy Library plugin to have a library that all your projects share in a git repository. In the documentation you can read about it in detail.

    If you have a lot of Pipelines that are mostly similar, the global variable mechanism provides a handy tool to build a higher-level DSL that captures the similarity. For example, all Jenkins plugins are built and tested in the same way, so we might write a step named buildPlugin:

    // vars/buildPlugin.groovy
    def call(body) {
        // evaluate the body block, and collect configuration into the object
        def config = [:]
        body.resolveStrategy = Closure.DELEGATE_FIRST
        body.delegate = config
        body()
    
        // now build, based on the configuration provided
        node {
            git url: "https://github.com/jenkinsci/${config.name}-plugin.git"
            sh "mvn install"
            mail to: "...", subject: "${config.name} plugin build", body: "..."
        }
    }
    

    Assuming the script has either been loaded as a Global Shared Library or as a Folder-level Shared Library the resulting Jenkinsfile will be dramatically simpler:

    Jenkinsfile (Scripted Pipeline)

    buildPlugin {
        name = 'git'
    }
    

    The example shows how a jenkinsfile passes name = git to the library. I currently use a similar setup and am very happy with it.