我正在转换企业版本,使其使用“矩阵”指令(https://www.jenkins.io/blog/2019/11/22/welcome-to-the-matrix/),但在优化它时遇到了麻烦。在矩阵前的世界中,我们有一个构建步骤(生成jar),然后是并行的“打包”步骤(生成linux和Windows发行版),本质上是一个“系统测试”阶段(在Windows上执行Windows和linux发行版)各种JVM),我们在打包和系统测试阶段进行了一些“代码质量”检查。
其中许多似乎很适合使用“矩阵”。因此,“打包”显然是构建Windows和Linux平台的矩阵。而“系统测试”是平台和jvm的另一个双轴矩阵。我可以轻松地使一个矩阵跟随另一个矩阵。到目前为止,一切都很好。
但是,我坚持将“代码质量”作为离群值。有没有一种方法可以使那些阶段与矩阵运行并行进行。创建构建后,它们是独立的(它们无需等待打包)。它们也很耗时,因此在两个矩阵阶段连续运行它们会使构建时间更长。詹金斯(Jenkins)抱怨如果将矩阵放在并行阶段中。
关于如何与矩阵并行运行非矩阵阶段的任何想法?
答案 0 :(得分:0)
我有一个针对自己问题的解决方法。
根据文档(https://www.jenkins.io/doc/book/pipeline/syntax/#declarative-matrix),我无法找到所需的内容。 “矩阵中的每个单元都可以包含一个或多个阶段,使用该单元的配置可以依次运行。请注意,一个阶段必须只有一个步骤,阶段,并行或矩阵中的一个,并且不能嵌套一个如果该阶段指令嵌套在并行或矩阵块本身中,则该指令中的并行或矩阵块。”
但是...。你可以作弊。我能够将矩阵转换为通用调度队列。也就是说,每个组合都会调用N个阶段-对我来说是2个阶段,我称它们为“准备”和“执行”。我传入一个附加的“ matrixtype”参数。matrixtype为矩阵本身获取1值,以及为非矩阵的每一行获取附加值。然后,我使用矩阵“排除”来确保非矩阵行仅执行一次。有效地,这会将非矩阵折叠成按矩阵类型区分的矩阵。
Original (parallel-stages in series with a subsequent matrix)
stage {
parallel {
stage("alpha") {
alpha(..)
}
stage("beta") {
beta(..)
}
// etc
}
}
stage {
matrix {
axes {
axis {
name 'ORIGAXIS'
values 'FOO','BAR','BAZ'
}
}
stages {
stage("First") {
originalFirst( ...)
}
stage("Second") {
originalSecond(...)
}
}
}
}
Replacement (parallel folded into matrix)
stage {
matrix {
axes {
axis {
name 'MATRIXTYPE
values 'ORIGINAL', 'ALPHA', 'BETA'
axis {
name 'ORIGAXIS'
values 'FOO','BAR','BAZ'
}
excludes {
// Execute Alpha and Beta only once (during 'FOO')
exclude {
axis {
name 'MATRIXTYPE'
values 'ALPHA', 'BETA'
}
axis {
name 'ORIGAXIS'
values 'BAR','BAZ'
}
}
}
}
stages {
stage("First") {
dispatchFirst( "${MATRIXTYPE}", ...)
}
stage("Second") {
dispatchSecond( "${MATRIXTYPE}", ...)
}
}
}
}
然后,dispatchFirst(..)和dispatchSecond(..)是共享库中检查矩阵类型并调用originalFirst(..),originalSecond(..),alpha(..),beta( ..)或视情况而定。它有点笨拙,相当于将并行阶段塞入矩阵,但它可以工作。而且,您可以获得并行化(构建速度优化)的好处
希望在将来会有更优雅的东西。
答案 1 :(得分:0)
我想出了一种恕我直言的“更好”的解决方案:
stage {
matrix {
axes {
axis {
name 'ORIGAXIS'
values 'ALPHA','BETA','BAR','BAZ'
}
}
stages {
stage ("alpha") {
when { expression { env.ORIGAXIS == "ALPHA" } }
steps {
alpha()
}
stage ("beta") {
when { expression { env.ORIGAXIS == "BETA" } }
steps {
beta()
}
}
stage ("Tests") {
when { allOf
expression { env.ORIGAXIS != "ALPHA" }
expression { env.ORIGAXIS != "BETA" }
}
stages {
stage("First") {
originalFirst( ...)
}
stage("Second") {
originalSecond(...)
}
}
}
}
}
当然,最终的布局并不完美。但是,它工作起来并不麻烦,而且仍然易于维护。