我们有一个这样的管道:
pipeline {
agent none
stages {
stage('Build') {
// ...
}
stage('Test') {
parallel {
stage('Test on Debian') {
agent {
label 'debian'
}
steps {
unstash 'compile-artifacts'
unstash 'dot-gradle'
sh './gradlew check --stacktrace'
}
post {
always {
junit '*/build/test-results/**/*.xml'
}
}
}
stage('Test on CentOS') {
agent {
label 'centos'
}
steps {
unstash 'compile-artifacts'
unstash 'dot-gradle'
sh './gradlew check --stacktrace'
}
post {
always {
junit '*/build/test-results/**/*.xml'
}
}
}
stage('Test on Windows') {
agent {
label 'windows'
}
steps {
unstash 'compile-artifacts'
unstash 'dot-gradle'
bat "gradlew.bat check --stacktrace"
}
post {
always {
junit '*/build/test-results/**/*.xml'
}
}
}
stage('Test on macOS') {
agent {
label 'macos'
}
steps {
unstash 'compile-artifacts'
unstash 'dot-gradle'
sh './gradlew check --stacktrace'
}
post {
always {
junit '*/build/test-results/**/*.xml'
}
}
}
}
}
}
}
每个阶段基本上都是相同的,除了Windows块中我已经知道如何处理的一行之外,是否有办法对这些阶段的公共部分进行模板化以消除重复?
我已经尝试过将循环内联,但这不是声明性管道允许您执行的操作。 :(
答案 0 :(得分:2)
您可以使用常规方法重构step{}
块:
def stageX(boolean linux)
{
unstash 'compile-artifacts'
unstash 'dot-gradle'
if (linux) {
sh './gradlew check --stacktrace' }
else {
bat "gradlew.bat check --stacktrace" }
}
您必须像在step{}
中那样调用它:
steps
{
script { stageX( true) } // or with false for your windows agent
}
当然,您可以对junit-plugin-call进行相同的操作:
def junitCall()
{
junit '*/build/test-results/**/*.xml'
}
并这样称呼它:
post {
always {
script { junitCall() }
}
}
您不会赢得很多行,但是它将大大改善代码的处理。如果您想进一步清理Jenkinsfile,可以将这些方法放入您导入的共享库中,这样就不会在您的Jenkinsfile中声明它们。
答案 1 :(得分:0)
目前基本上无法完成您想做的事情。正如https://jenkins.io/doc/book/pipeline/shared-libraries/#defining-declarative-pipelines所述:
到目前为止,只能在共享库中定义整个管道 时间。这只能在vars / *。groovy中完成,并且只能在调用中完成 方法。一次只能执行一条声明性管道 构建,如果您尝试执行第二个构建,则构建将 结果失败了。
因此,您可以定义方法来捆绑多个步骤,也可以将整个管道捆绑在共享库中,但两者之间什么也没有。真可惜。