使用 Jenkins 管道的矩阵配置

Matrix configuration with Jenkins pipelines

Jenkins Pipeline 插件(又名工作流)可以与其他 Multibranch 插件一起扩展,以自动构建分支和拉取请求。

运行 多重配置的首选方式是什么?例如,使用 Java 7 和 Java 8 进行构建。这通常称为矩阵配置(因为有多种组合,例如语言版本、框架版本...)或构建变体。

我试过了:

有推荐的方法吗?

TLDR:Jenkins.io 希望您为每个构建使用 节点

Jenkins.io: In pipeline coding contexts, a "node" is a step that does two things, typically by enlisting help from available executors on agents:

  1. Schedules the steps contained within it to run by adding them to the Jenkins build queue (so that as soon as an executor slot is free on a node, the appropriate steps run)

  2. It is a best practice to do all material work, such as building or running shell scripts, within nodes, because node blocks in a stage tell Jenkins that the steps within them are resource-intensive enough to be scheduled, request help from the agent pool, and lock a workspace only as long as they need it.

阶段中的 Vanilla Jenkins 节点块看起来像:

stage 'build' {
    node('java7-build'){ ... }
    node('java8-build'){ ... }
}

进一步扩展 Cloudbees 写的关于 parallelism and distributed builds with Jenkins 的这个概念。您的 Cloudbees 工作流程可能如下所示:

stage 'build' {
    parallel 'java7-build':{
      node('mvn-java7'){ ... }
    }, 'java8-build':{
      node('mvn-java8'){ ... }
    }
}

您在管道中可视化不同构建的要求可以通过任一工作流来满足,但我相信 Jenkins 文档中的最佳实践。


编辑

处理可视化 @Stephen would like to see, He's right - it doesn't work! The issue has been raised with Jenkins and is documented here, the resolution of involving the use of 'labelled blocks' is still in progress :-(

Q: Is there documentation letting pipeline users not to put stages inside of parallel steps?

A: No, and this is considered to be an incorrect usage if it is done; stages are only valid as top-level constructs in the pipeline, which is why the notion of labelled blocks as a separate construct has come to be ... And by that, I mean remove stages from parallel steps within my pipeline.

如果您尝试在并行作业中使用阶段,您将会遇到麻烦。

ERROR: The ‘stage’ step must not be used inside a ‘parallel’ block.

似乎至少在 BlueOcean UI 之后松了一口气。这是我得到的(tk-* 节点是并行步骤):

如@StephenKing 所述,Blue Ocean 将比当前舞台视图更好地显示平行 b运行ches。计划中的即将推出的舞台视图版本将能够显示所有 b运行ches,尽管它不会在视觉上指示任何嵌套结构(看起来与连续 运行 配置相同)。

无论如何,更深层次的问题是您基本上只会获得整个构建的 pass/fail 状态,等待对 JENKINS-27395 和相关请求的解决。

为了在多个平台上测试每个提交,我使用了这个基本的 Jenkinsfile 框架:

def test_platform(label, with_stages = false)
{
    node(label)
    {
        // Checkout
        if (with_stages) stage label + ' Checkout'
        ...

        // Build
        if (with_stages) stage label + ' Build'
        ...

        // Tests
        if (with_stages) stage label + ' Tests'
        ...
    }
}

/*
parallel ( failFast: false,
    Windows: { test_platform("Windows") },
    Linux:   { test_platform("Linux")   },
    Mac:     { test_platform("Mac")     },
)
*/

test_platform("Windows", true)
test_platform("Mac",     true)
test_platform("Linux",   true)

有了这个,从顺序执行切换到并行执行就相对容易了,它们各有利弊:

  • 并行执行运行得更快,但它不包含阶段标签
  • 顺序执行要慢得多,但多亏了阶段,你会得到一份详细的报告,标记为"Windows Checkout"、"Windows Build"、"Windows Tests"、"Mac Checkout"等)

我暂时使用顺序执行,直到找到更好的解决方案。

我建议 Declarative Matrix 作为 Jenkins 中 运行 多个配置的首选方式。它允许您为每个配置执行定义的阶段,而无需重复代码。

示例:

pipeline {
    agent none
    stages {
        stage('Test') {
            matrix {
                agent {
                    label "${NODENAME}"
                }
                axes {
                    axis {
                        name 'NODENAME'
                        values 'java7node', 'java8node'
                    }
                }
                stages {
                    stage('Test') {
                        steps {
                            echo "Do Test for ${NODENAME}"
                        }
                    }
                }
            }
        }
    }
}

请注意,声明式矩阵是本机声明式管道功能,因此无需安装额外的插件。

Jenkins blog post 关于矩阵指令。