如何在Jenkins声明性流水线中创建方法?

96

Jenkins的脚本化管道中,我们可以创建方法并调用它们。

在Jenkins声明式管道中是否也可以实现这一点?如果可以,具体如何操作?


3
可以的。 - Markus
请问您能分享一下那个的语法吗?谢谢。 - vinesh vini
Jenkins流水线是Groovy脚本。因此,您只需要遵循Groovy语法即可。 - Markus
1
其实直到几个版本之前,声明式流水线是无法实现这一点的。 - StephenKing
我会很感激提供一个例子,因为作用域似乎会产生影响。 - Hugo
如果已经通过 YAML 定义了管道,我该如何从 YAML 调用 Groovy 脚本? - Mike
4个回答

106

新版本的声明性流水线支持这一点,而以前(约2017年中期)是不可能的。您可以像从Groovy脚本中预期的那样声明函数:

pipeline {
    agent any
    stages {
        stage('Test') {
            steps {
                whateverFunction()
            }
        }
    }
}

void whateverFunction() {
    sh 'ls /'
}

2
我已经能够使其正常工作,但是它删除了在Blue Ocean GUI编辑器中编辑流水线的功能。你知道如何绕过这个问题吗?我大部分的编辑工作都是通过文本编辑器直接在Jenkinsfile中完成的,但是在UI中快速地进行预备工作也是很好的。我通过暂时注释掉该函数来解决了这个问题。 - Damon
1
我正在尝试定义一个定义阶段的函数,但似乎无法正常工作(语法错误,期望“stage”)。他们只支持运行定义步骤的函数吗? - Will Brode
3
这真的很酷。但是,这在哪里有记录呢?我找不到任何描述这种能力的资源。我只找到了如何导入外部共享Groovy库的文档。我只发现了这个SO答案,可以将它们嵌入到Jenkinsfile本身中,这真的很有用。Jenkins问题跟踪器收到了一些建议,但被标记为wontfix状态,例如:https://issues.jenkins-ci.org/browse/JENKINS-41396 - gertvdijk
即使文档此处中提到我们可以使用步骤,但这种方法在post块中不可用。 - Eric Salemi
@EricSalemi,我猜你需要将调用包装在script { }中。 - StephenKing
显示剩余2条评论

31
您可以创建这样的Groovy函数,并将其保存在您配置为托管库的Git中(也要在Jenkins中进行配置):
/path/to/repo-shared-library/vars/sayHello.groovy:

Content:

def call(String name = 'human') {
    echo "Hello, ${name}."
}

您可以在管道中使用以下方法来调用它:
@Library('name-of-shared-library')_
pipeline {
    agent any
    stages {
        stage('test') {
            steps {
                sayHello 'Joe'
            }
        }
    }
}

输出:

[Pipeline] echo
Hello, Joe.

您可以重复使用保存在库中的现有函数。


1
我似乎找不到关于“Step does not take a single required parameter - use named parameters instead”的答案,我在方法调用处确切地遇到了这个错误。 - Benjamin Vison
如果你想在Groovy中有多个函数,该怎么办?或者建议每个函数都有一个Groovy吗? - ealeon
@ealeon,你可以在共享库中拥有多个函数,并从管道内部调用它们。 - lvthillo

25

这对我很有效。可以使用Blue Ocean GUI查看,但是当我使用Blue Ocean GUI进行编辑时,它会删除方法“def showMavenVersion(String a)”。

pipeline {
agent any
stages {
    stage('build') {
        agent any
        steps {
            script {
                showMavenVersion('mvn version')
            }
        }
    }
}

}

def showMavenVersion(String a) {
        bat 'mvn -v'
        echo a
}

3
能否将stage('build')移动到showMavenVersion方法中? - Marteng

23
您还可以拥有单独的 Groovy 文件来存储所有函数(只是为了保持结构化和清洁),您可以通过管道加载文件来使用它们: JenkinsFile.groovy
Map modules = [:]
pipeline {
    agent any
    stages {
        stage('test') {
            steps {
                script{
                    modules.first = load "first.groovy"
                    modules.first.test1()
                    modules.first.test2()
                }
            }
        }
    }
}

first.groovy

def test1(){
    //add code for this method
}
def test2(){
    //add code for this method
}
return this

1
你能解释一下 return this 语句吗?为什么需要这个语句? - YoavKlein
1
这可以通过明确定义每个文件相对于彼此保存的位置来更清晰地表达。 - macetw
1
我猜load "first.groovy"会执行Groovy脚本,而"return this"会返回对包含方法的脚本本身的引用,否则您将无法得到对这些方法的引用。 - Veaceslav Serghienco

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