如何在本地覆盖Jenkinsfile库函数?

7

我有一个标准化的声明性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

2个回答

4

你不能覆盖定义在库脚本内部的函数。但是你可以考虑将自定义后构建步骤定义为一个传递给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';
}

Jenkinsfile

@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

希望这能有所帮助。

3
可以的。原文如下:那行得通。结果我也可以在管道中定义一个函数并传递它,而不是显式地定义闭包定义:@Library('default_jenkins_libs') _ default_pipeline({ CustomDefinedStep() }) def CustomDefinedStep() { echo 'Running part one' echo 'Running part two' echo 'Running part three' }对你的代码只有一个更改,“def call(body = null) {”需要改为“def call(def body = null) {”,否则我会收到“No matching signature.”的错误消息。谢谢!! - Mike Rysanek

0
事实上,可以通过从共享库中的全局变量覆盖管道步骤来实现,例如将其命名为stage.groovy
请参见我在此处提供的详细答案: Jenkinsfile中的常见包装器 以及GitHub中的示例。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接