groovy 将整个Jenkins舞台提取到共享库中?

xzv2uavs  于 2022-11-01  发布在  Jenkins
关注(0)|答案(2)|浏览(167)

有没有可能将整个stage('foo') {...}定义提取到Jenkins的共享库中?文档非常清楚如何提取单个步骤,但是我找不到任何方法来提取整个阶段,将其参数化,然后全局重用它。我以为可能只使用return stage...就可以了,但是它会错误地返回无效值。

i5desfxk

i5desfxk1#

这取决于您使用的是脚本化还是声明性管道。

脚本化管道更加灵活,例如,它允许您根据某些条件创建阶段(每个管道运行可以有不同数量和类型的阶段)。在这种管道中,您可以将一个完整阶段提取到共享库类中,并从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-脚本化的管道允许你做这样的事情。

声明式管道则更加严格和固执己见。如果涉及到阶段的数量和名称,它是固定的(您不能动态地对每个构建中出现的阶段以及它们的名称进行建模)。您仍然可以利用共享库类,但是您只能在stage('Name') { steps {} }块中的script {}块中执行它们,这意味着您不能将整个阶段提取到单独的类中,而只是在步骤级别执行的某个部分。

// 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)
                }
            }
        }
    }
}

如果我们尝试在声明性管道中的script {}块外部执行new DeclarativeFooStage(this).execute('something', false),则会出现编译错误。
结论
脚本式管道还是声明式管道取决于具体的用例。如果您希望在对管道业务逻辑建模时获得最大的灵活性,那么脚本式管道可能是个不错的选择。但是,它也有一定的代价。例如,脚本化管道不支持从特定阶段重新启动管道生成-只有声明性管道才支持此操作(假设管道中有10个阶段,第7个阶段由于某个愚蠢的错误而失败,您希望从第7个阶段重新开始构建-在脚本化管道中,您必须从头开始重新运行,而声明性管道可以通过记住所有6个先前阶段的结果从第7个阶段重新开始)。

3df52oht

3df52oht2#

为了完成Szymon Stepniak的回答,我将在这里留下注意,在声明性管道中,您也可以共享整个管道:

// vars/myDeliveryPipeline.groovy
def call(Map pipelineParams) {

    pipeline {
        agent any
        stages {
            stage('build') {
                ...
            }

            stage ('test') {
                ...
            }

            ...
        }
    }
}

然后叫它

// Jenkinsfile
myDeliveryPipeline(foo: 'FOO', bar: 'BAR')

但是,只要记住你可能只调用一个管道在一个Jenkins文件,使它不是很可定制。

来源

https://www.jenkins.io/blog/2017/10/02/pipeline-templates-with-shared-libraries/

相关问题