How to override a Jenkinsfile library function locally?
Asked Answered
G

2

7

I have a standardized declarative Jenkinsfile used in many projects. I have moved the entire pipeline into a library, so my Jenkinsfile looks like this:

@Library('default_jenkins_libs') _
default_pipeline();

The library (var/default_pipeline.groovy):

def call() {
pipeline {
  node { <snip> }
  stages {
    stage('Lint and style') {
      steps {
      //stuff
      }
    }
    //etc...
    stage('Post-build') {
      steps {
        PostBuildStep();
      }
    }
  }
}

def PostBuildStep() {
  echo 'Running default post-build step';
}

I want to be able to add a definition to the actual pipeline code in the Jenkinsfile, like so:

@Library('default_jenkins_libs') _

def PostBuildStep() {
  echo 'Running customized post-build step'
  //do custom stuff
}

default_pipeline();

I have not been able to figure out how to do this. I've suspect this may be doable by the library calling the object represented by the Jenkinsfile and calling its "PostBuildStep()", maybe like 'parent.PostBuildStep()" but I do not have the class structure/naming reference.

Any suggestions? Bottom line is, I want a standardized pipeline that is changeable en masse via a library change, but still give some control to jobs that use it.

TIA

Geraldgeralda answered 10/2, 2018 at 18:35 Comment(0)
P
4

You cannot override a function defined inside library script. But you can consider defining custom post build step as a closure passed to default_pipeline(). Consider following example:

vars/default_pipeline.groovy

def call(body = null) {
    pipeline {
        agent any
        stages {
            stage('Build') {
                steps {
                    script {
                        body != null ? body() : PostBuildStep()
                    }
                }
            }
        }
    }
}

def PostBuildStep() {
    echo 'Running default post-build step';
}

Jenkinsfile

@Library('default_jenkins_libs') _

default_pipeline({
    echo 'Running customized post-build step'
})

In this case default_pipeline has a single optional parameter that is a closure that defines your custom post build step. Running following example will produce following output:

[Pipeline] node
Running on Jenkins in /var/jenkins_home/workspace/test-pipeline
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Build)
[Pipeline] script
[Pipeline] {
[Pipeline] echo
Running customized post-build step
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

Hope it helps.

Promising answered 10/2, 2018 at 19:57 Comment(1)
That worked. Turns out I can also define a function in the pipeline and pass it, instead of an explicit closure definition: @Library('default_jenkins_libs') _ default_pipeline({ CustomDefinedStep() }) def CustomDefinedStep() { echo 'Running part one' echo 'Running part two' echo 'Running part three' } Only one correction to your code, "def call(body = null) {" needs to be "def call(def body = null) {" otherwise I got a "No matching signature." Thank you!!Geraldgeralda
L
0

In fact, it is possible to override a pipeline step with a global variable from the shared library, for example by naming it stage.groovy.

Please see the detailed answer I gave here: Common wrapper in Jenkinsfile and the examples in GitHub.

Load answered 20/5, 2019 at 8:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.