Matrix configuration with Jenkins pipelines
Asked Answered
A

5

28

The Jenkins Pipeline plugin (aka Workflow) can be extended with other Multibranch plugins to build branches and pull requests automatically.

What would be the preferred way to run multiple configurations? For example, building with Java 7 and Java 8. This is often called matrix configuration (because of the multiple combinations such as language version, framework version, ...) or build variants.

I tried:

  • executing them serially as separate stage steps. Good, but takes more time than necessary.
  • executing them inside a parallel step, with or without nodes allocated inside them. Works but I cannot use the stage step inside parallel for known limitations on how it would be visualized.

Is there a recommended way to do this?

Astonied answered 20/6, 2016 at 10:55 Comment(0)
N
1

It seems like there is relief coming at least with the BlueOcean UI. Here is what I got (the tk-* nodes are the parallel steps):

enter image description here

Nightly answered 19/7, 2016 at 19:44 Comment(1)
This does not really answer the question OP asked.Sago
P
16

TLDR: Jenkins.io wants you to use nodes for each build.

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 Node blocks within a stage would look like:

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

Further extending this notion Cloudbees writes about parallelism and distributed builds with Jenkins. Cloudbees workflow for you might look like:

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

Your requirements of visualizing the different builds in the pipeline would could be satisfied with either workflow, but I trust the Jenkins documentation for best practice.


EDIT

To address the visualization @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.

If you try to use a stage in a parallel job, you're going to have a bad time.

ERROR: The ‘stage’ step must not be used inside a ‘parallel’ block.
Portion answered 13/7, 2016 at 12:19 Comment(4)
Sure, that's why this problem exists. Multiple node below one stage. You don't see in the visualization, which part of the parallel (that wraps the node blocks) is still running and which failed.Nightly
It sounds like your question should focus more on how to visualize parallel jobs rather than the preferred / recommended way to run parallel jobs - the linked documents are the recommended wayPortion
It's not my question to be precise ;) As the part you answered was pretty clear, I was more focussed on the part to make the parallel more visible.Nightly
While my point for offering this bounty wasn't covered by your answer (as it seems that there's currently no better way to distinguish parallel steps), I appreciate your efforts. So I'll award the bounty to you.Nightly
R
7

I would suggest Declarative Matrix as a preferred way to run multiple configurations in Jenkins. It allows you to execute the defined stages for every configuration without code duplication.

Example:

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}"
                        }
                    }
                }
            }
        }
    }
}

Note that declarative Matrix is a native declarative Pipeline feature, so no additional Plugin installation needed.

Jenkins blog post about the matrix directive.

Rubellite answered 7/2, 2020 at 13:5 Comment(0)
O
3

As noted by @StephenKing, Blue Ocean will show parallel branches better than the current stage view. A planned upcoming version of the stage view will be able to show all the branches, though it will not visually indicate any nesting structure (would look the same as if you ran the configurations serially).

In any event, the deeper issue is that you will essentially only get a pass/fail status for the build overall, pending a resolution to JENKINS-27395 and related requests.

Occlusion answered 25/8, 2016 at 15:25 Comment(0)
O
2

In order to test each commit on several platforms, I've used this base Jenkinsfile skeleton:

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)

With this it's relatively easy to switch from a sequential to a parallel execution, each of them having their pros and cons:

  • Parallel execution runs much faster, but it doesn't contain the stages labelling
  • Sequential execution is much slower, but you get a detailed report thanks to stages, labelled as "Windows Checkout", "Windows Build", "Windows Tests", "Mac Checkout", etc.)

I'm using the sequential execution for the time being, until I find a better solution.

Offset answered 29/8, 2016 at 9:21 Comment(0)
N
1

It seems like there is relief coming at least with the BlueOcean UI. Here is what I got (the tk-* nodes are the parallel steps):

enter image description here

Nightly answered 19/7, 2016 at 19:44 Comment(1)
This does not really answer the question OP asked.Sago

© 2022 - 2024 — McMap. All rights reserved.