0

So I have a use case with Jenkinsfile that I know is not common, and I haven't found a solution for it yet.

Background

We currently have a multi-branch pipeline job configured to build multiple branches. This is uses to run system-testing of the products across multiple release. The Jenkins job

  1. Clone all required repositories
  2. Deploy the environment
  3. Execute the automated test cases
  4. Undeploy the environment

In order to avoid having to define the same Jenkinsfile on each branches, we created a shared library. The shared library defines the Declarative pipeline stages for the Jenkins file. The shared library has the following:

/* File name var/myStep.groovy */
def call(Map pipelineParams) {
    callASharedLibraryFunction()

    properties([
        parameters(sharedLibraryGetParameters(pipelineParams))
    ])

    pipeline {
        // snip
        stages {
            stage("clone repos") { }
            stage("Deploy environment") { }
            stage("Executed Tests") { }
            stage("Undeploy environment") { }
        }
        // post directives
    }
}

And the Jenkins file simply defines a map, and then call myStep call.

e.g.:

/* Sample Jenkinsfile */
pipelineParams = [
    FOO = "foo"
]
myStep pipelineParams

The problem

We now have a need for another Jenkins job, where some of the stages will be the same. For example, the new jobs will need to

  1. Clone all required repositories
  2. Deploy the environment
  3. Do something else

And changing the behaviour of a common stage (e.g.: Clone the repo), should take effect across all the jobs that define this stage. I know we can use the when directive in the stage, however from a usability perspective, I want the jobs to be different as they are exercising different things. And the users of one job don't care about the additional stages the other job runs.

I want to avoid code duplication, and better yet, I don't want to duplicate the stage code. (including steps, when, post, etc..).

Is there a way a shared library can define the stage "implementation" with all the directives (steps, when, post, etc) once, but have it get called multiple times?

e.g.:

/* File: vars/cloneReposStageFunction.groovy */
def call() { 
    stage("Clone Repos") { }
}

/* File: vars/myStep.groovy */
def call(Map pipelineParams) {
    pipeline {
        // snip
        stages {
            cloneReposStageFunction()
            stage("Deploy environment") { }
            stage("Executed Tests") { }
            stage("Undeploy environment") { }
        }
        // post directives
    }
}

/* File: vars/myNewStep.groovy */
def call(Map pipelineParams) {
    pipeline {
        // snip
        stages {
            cloneReposStageFunction()
            stage("Deploy environment") { }
            stage("Do something else") { }
        }
        // post directives
    }
}
bkhouri
  • 243
  • 6
  • 14

1 Answers1

1

It's an open Jenkins' Feature Request.

I've seen different ways to template a pipeline, but it's far from what you'd like to achieve.

hakamairi
  • 4,464
  • 4
  • 30
  • 53