【问题标题】:How to override a Jenkinsfile library function locally?如何在本地覆盖 Jenkinsfile 库函数?
【发布时间】:2018-02-10 18:35:22
【问题描述】:

我有一个在许多项目中使用的标准化声明性 Jenkinsfile。我已将整个管道移至库中,因此我的 Jenkinsfile 如下所示:

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

库(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';
}

我希望能够向 Jenkinsfile 中的实际管道代码添加定义,如下所示:

@Library('default_jenkins_libs') _

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

default_pipeline();

我无法弄清楚如何做到这一点。我怀疑这可以通过调用由 Jenkinsfile 表示的对象并调用其“PostBuildStep()”的库来实现,可能类似于“parent.PostBuildStep()”,但我没有类结构/命名参考。

有什么建议吗?底线是,我想要一个标准化的管道,它可以通过库更改来整体更改,但仍然对使用它的作业进行一些控制。

TIA

【问题讨论】:

    标签: jenkins groovy declarative


    【解决方案1】:

    您不能覆盖在库脚本中定义的函数。但是您可以考虑将自定义后期构建步骤定义为传递给default_pipeline() 的闭包。考虑以下示例:

    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';
    }
    

    Jenkins 文件

    @Library('default_jenkins_libs') _
    
    default_pipeline({
        echo 'Running customized post-build step'
    })
    

    在这种情况下,default_pipeline 有一个可选参数,它是一个闭包,用于定义您的自定义后期构建步骤。运行以下示例将产生以下输出:

    [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
    

    希望对你有帮助。

    【讨论】:

    • 那行得通。结果我也可以在管道中定义一个函数并传递它,而不是显式的闭包定义:@Library('default_jenkins_libs') _ default_pipeline({ CustomDefinedStep() }) def CustomDefinedStep() { echo 'Running part one' echo '运行第二部分' echo '运行第三部分' } 只有一个更正你的代码,“def call(body = null){”需要是“def call(def body = null){”否则我得到一个“没有匹配签名。”谢谢!!
    【解决方案2】:

    事实上,可以使用共享库中的全局变量覆盖管道步骤,例如将其命名为stage.groovy

    请看我在这里给出的详细答案: Common wrapper in Jenkinsfile 以及GitHub 中的示例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-27
      • 2014-05-05
      • 2018-12-05
      • 1970-01-01
      相关资源
      最近更新 更多