有没有可能将整个stage('foo') {...}定义提取到Jenkins的共享库中?文档非常清楚如何提取单个步骤,但是我找不到任何方法来提取整个阶段,将其参数化,然后全局重用它。我以为可能只使用return stage...就可以了,但是它会错误地返回无效值。
stage('foo') {...}
return stage...
i5desfxk1#
这取决于您使用的是脚本化还是声明性管道。
脚本化管道更加灵活,例如,它允许您根据某些条件创建阶段(每个管道运行可以有不同数量和类型的阶段)。在这种管道中,您可以将一个完整阶段提取到共享库类中,并从node {}块内部调用它。请考虑以下示例:
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-脚本化的管道允许你做这样的事情。
ScriptedFooStage.execute()
name
声明式管道则更加严格和固执己见。如果涉及到阶段的数量和名称,它是固定的(您不能动态地对每个构建中出现的阶段以及它们的名称进行建模)。您仍然可以利用共享库类,但是您只能在stage('Name') { steps {} }块中的script {}块中执行它们,这意味着您不能将整个阶段提取到单独的类中,而只是在步骤级别执行的某个部分。
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个阶段重新开始)。
new DeclarativeFooStage(this).execute('something', false)
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/
2条答案
按热度按时间i5desfxk1#
这取决于您使用的是脚本化还是声明性管道。
脚本化管道更加灵活,例如,它允许您根据某些条件创建阶段(每个管道运行可以有不同数量和类型的阶段)。在这种管道中,您可以将一个完整阶段提取到共享库类中,并从
node {}
块内部调用它。请考虑以下示例:则 Jenkinsfile 可能如下所示:
正如你所看到的,整个阶段都被封装在
ScriptedFooStage.execute()
方法中,它的名字也取自参数name
-脚本化的管道允许你做这样的事情。声明式管道则更加严格和固执己见。如果涉及到阶段的数量和名称,它是固定的(您不能动态地对每个构建中出现的阶段以及它们的名称进行建模)。您仍然可以利用共享库类,但是您只能在
stage('Name') { steps {} }
块中的script {}
块中执行它们,这意味着您不能将整个阶段提取到单独的类中,而只是在步骤级别执行的某个部分。而 Jenkinsfile 可能如下所示:
如果我们尝试在声明性管道中的
script {}
块外部执行new DeclarativeFooStage(this).execute('something', false)
,则会出现编译错误。结论
脚本式管道还是声明式管道取决于具体的用例。如果您希望在对管道业务逻辑建模时获得最大的灵活性,那么脚本式管道可能是个不错的选择。但是,它也有一定的代价。例如,脚本化管道不支持从特定阶段重新启动管道生成-只有声明性管道才支持此操作(假设管道中有10个阶段,第7个阶段由于某个愚蠢的错误而失败,您希望从第7个阶段重新开始构建-在脚本化管道中,您必须从头开始重新运行,而声明性管道可以通过记住所有6个先前阶段的结果从第7个阶段重新开始)。
3df52oht2#
为了完成Szymon Stepniak的回答,我将在这里留下注意,在声明性管道中,您也可以共享整个管道:
然后叫它
但是,只要记住你可能只调用一个管道在一个Jenkins文件,使它不是很可定制。
来源
https://www.jenkins.io/blog/2017/10/02/pipeline-templates-with-shared-libraries/