jenkins - 将整个 Jenkins 阶段提取到共享库?

标签 jenkins groovy jenkins-pipeline

是否可以带整个stage('foo') {...}定义并将其提取到 Jenkins 中的共享库中?文档非常清楚如何提取单个步骤,但我找不到任何方法来获取整个阶段,对其进行参数化并在全局范围内重新使用它。我想也许只是 return stage...会工作,但它错误地显示为无效的返回值。

最佳答案

这取决于您是否使用 脚本化 声明式 管道。

脚本化管道 更灵活,它允许你例如根据某些条件创建阶段(每个管道运行可以有不同数量和类型的阶段)。在这种管道中,您可以将完整阶段提取到共享库类并从 node {} 内部调用它。堵塞。考虑以下示例:

// src/ScriptedFooStage.groovy
class ScriptedFooStage {
    private final Script script

    ScriptedFooStage(Script script) {
        this.script = script
    }

    // You can pass as many parameters as needed
    void execute(String name, boolean param1) {
        script.stage(name) {
            script.echo "Triggering ${name} stage..."
            script.sh "echo 'Execute your desired bash command here'"

            if (param1) {
                script.sh "echo 'Executing conditional command, because param1 == true'"
            }
        }
    }
}

然后 Jenkinsfile 可能如下所示:

node {
    new ScriptedFooStage(this).execute('Foo', true)
}

如您所见,整个阶段都被封装在 ScriptedFooStage.execute() 中。方法。它的名字也取自参数 name - 脚本化管道允许你做这样的事情。

声明式管道 另一方面更加严格和固执己见。如果涉及阶段的数量及其名称(您无法动态建模每个构建存在哪些阶段以及它们的名称是什么),它是固定的。您仍然可以利用共享库类,但您只能在 script {} 中执行它们。块内stage('Name') { steps {} }堵塞。这意味着您不能将整个阶段提取到单独的类中,而只能将某些部分提取到步骤级别。考虑以下示例:

// src/DeclarativeFooStage.groovy
class DeclarativeFooStage {
    private final Script script

    DeclarativeFooStage(Script script) {
        this.script = script
    }

    // You can pass as many parameters as needed
    void execute(String name, boolean param1) {
        script.echo "Triggering script with name == ${name}"
        script.sh "echo 'Execute your desired bash command here'"

        if (param1) {
            script.sh "echo 'Executing conditional command, because param1 == true'"
        }
    }
}

Jenkinsfile 可能如下所示:

// Jenkinsfile
pipeline {
    agent any

    stages {
        stage('Foo') {
            steps {
                script {
                    new DeclarativeFooStage(this).execute('something', false)
                }
            }
        }
    }
}

如果我们尝试执行 new DeclarativeFooStage(this).execute('something', false)外面script {}在声明性管道中阻塞我们会得到编译错误。

结论

脚本化或声明性管道之间的选择取决于特定的用例。如果您想在建模管道业务逻辑时获得最佳灵活性,脚本化管道可能是不错的选择。然而,它带来了一些代价。例如,脚本管道不支持从特定阶段重新启动管道构建 - 这仅由声明性管道支持。 (假设您在管道中有 10 个阶段,第 7 阶段由于一些愚蠢的错误而失败,并且您想从第 7 阶段重新开始构建 - 在脚本化管道中,您必须从一开始就重新运行,而声明性管道可以重新启动从第 7 阶段开始,记住所有 6 个前阶段的结果)。

关于jenkins - 将整个 Jenkins 阶段提取到共享库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53201656/

相关文章:

gradle - 如何使用GroovyShell()。run()返回某些内容?

java - DH key 大小必须是 64 的倍数,并且只能在 512 到 2048(含)之间

java - Jenkins:每个环境(DEV、QA、UAT 和 PROD)和包 war 的参数化属性文件

selenium - 如何通过 Linux VM 运行 InternetExplorerDriver?

jenkins - 非法参数异常 : Expected named arguments (Jenkins)

grails - 使用 Grails 3 渲染空的 HTTP 响应

Jenkins slack发送漂亮的网址

csv - Jenkins 管道,解析 csv

jenkins - 在 Jenkins 管道中报告 shell 脚本测试错误而不终止作业

java - 运行 ant build.xml 并传递 "environment url"参数