Specifying a matrix of one or more dimensions

Users may need to run the same actions on a bunch of different configurations. If they make multiple copies of the same stages in their pipelines to run these actions on different configurations, when they need to make changes, they have to make the same changes in multiple places throughout their pipeline. Maintaining even a small number of configurations is difficult for larger pipelines.

The Declarative Pipeline Matrix section allows users to specify a list stages once and then run that same list in parallel on multiple configurations. The new matrix section executes a set of one or more Pipeline stages multiple times - once for every combination defined in the matrix. Matrix combinations are generated from static lists of predefined values. Filters can also be provided to exclude specific combinations.

Adding axes and values

The Matrix feature is a child stage similar to the parallel directive. Values are only specified statically in the pipeline and there is no limit on the number of dimensions or number of values per dimension. Values from the matrix dimensions are exposed and consumed as environment variables.

The pipeline then generates a matrix of cells based on the combination of all the values in each axis, and then executes a list of one or more stages for each cell in that matrix. Each cell is executed in parallel. All cells execute on the same agent, unless otherwise specified (same as stages inside a parallel directive). The stages in each cell are executed sequentially.

Sample matrix axes with values

The following example displays the axes section of a matrix block in a pipeline that runs tests on Linux, OS X, and Windows for browsers Chrome, Firefox, IE, and Safari. To achieve this pipeline, two axes with name and values properties are defined in a matrix block contained in a pipeline stage block.

pipeline {
    agent none
    stages {
        stage("foo") {
            matrix {
                axes { (1)
                    axis { (2)
                        name 'OS_VALUE'  (3)
                        values "linux", "windows", "mac"  (4)
                    }
                    axis {
                        name 'BROWSER_VALUE'
                        values "firefox", "chrome", "safari", "ie"
                    }
                }
...
1 Required
2 At least 1
3 Required, not empty, unique
4 Required, at least 1 param

Filtering a matrix using excludes

Pipeline authors can specify filter expressions that select cells to be excluded from the expanded set of matrix cells. Filters are constructed using a basic directive structure of one or more of exclude axis directives each with a list of either values or notValues.

Sample excludes

The following is an example exclude section of a matrix block in a pipeline that runs tests for IE on Windows only and runs tests for Safari only on OS X and Windows(excluding 'linux'). The optional exclude section includes the axes with name and values properties, specifying what needs to be excluded.

...
excludes {  (1)
          exclude {  (2)
              axis {  (3)
                  name 'OS_VALUE'  (4)
                                  (5)
                  values 'linux'
              }
              axis {
                  name 'BROWSER_VALUE'
                  values 'safari'
              }
          }
          exclude {
              axis {
                  name 'OS_VALUE'
                  notValues 'windows'
              }
              axis {
                  name 'BROWSER_VALUE'
                  values 'ie'
              }
          }
      }
...
1 Optional
2 At least 1
3 At least 1
4 Required, not empty, unique per exclude
5 Require values or notValues, at least 1 param

Configuring cell environment

The Matrix section allows users to efficiently configure the overall environment for each cell, by adding stage directives under the matrix itself. These directives include agent, environment, input, options, post, tools, and when. These directives behave the same as they would on a stage, but they can also accept values provided by the matrix for each cell. For more information on the directives, see Using Declarative Pipeline syntax - Directives in the Pipeline syntax guide.

Sample environment configuration

...
          matrix {
              axes {
                  axis {
                      name 'OS_VALUE'
                      values "linux", "windows", "mac"
                  }
              }
              agent {
                  label "${OS_VALUE}-agent"
              }
              tools {
                  maven "apache-maven-${MAVEN_VERSION}"
              }
              when {
                  environment name: "WHICH_AGENT", value: "${OS_VALUE} agent"
              }
              environment {
                  OS_VALUE = "${OS_VALUE}-os"
                  OVERRIDE_TWICE = "overrode twice, in first ${OS_VALUE} branch"
                  OVERRIDE_PER_NESTED = "overrode per nested, in first ${OS_VALUE} branch"
                  DECLARED_PER_NESTED = "declared per nested, in first ${OS_VALUE} branch"
                  MAVEN_VERSION = "3.0.1"
              }

...

Complete sample matrix pipeline

The following example displays a pipeline that runs tests on Linux, OS X, and Windows for browsers Chrome, Firefox, IE, and Safari. The pipeline runs tests for IE on Windows only and runs tests for Safari only on OS X and Windows(excluding 'linux').

pipeline {
    agent none
    stages {
        stage("foo") {
            matrix {
                axes { (1)
                    axis { (2)
                        name 'OS_VALUE'  (3)
                        values "linux", "windows", "mac"  (4)
                    }
                    axis {
                        name 'BROWSER_VALUE'
                        values "firefox", "chrome", "safari", "ie"
                    }
                }
                excludes {  (5)
                    exclude {  (6)
                        axis {  (7)
                            name 'OS_VALUE'  (8)
				                                    (9)
                            values 'linux'
                        }
                        axis {
                            name 'BROWSER_VALUE'
                            values 'safari'
                        }
                    }
                    exclude {
                        axis {
                            name 'OS_VALUE'
                            notValues 'windows'
                        }
                        axis {
                            name 'BROWSER_VALUE'
                            values 'ie'
                        }
                    }
                }
		            (10)
                stages {
                    stage("first") {
                        steps {
                            echo "First branch"
                            echo "OS=${OS_VALUE}"
                            echo "BROWSER=${BROWSER_VALUE}"
                        }
                    }
                    stage("second") {
                        steps {
                            (11)
				echo "Second branch"
                        }
                    }
                }
            }
        }
    }
}
1 Required
2 At least 1
3 Required, not empty, unique
4 Required, at least 1 param
5 Optional
6 At least 1
7 At least 1
8 Required, not empty, unique per exclude
9 Required, values or notValues, at least 1 param
10 Agent, etc.
11 Second stage steps
Copyright © 2010-2020 CloudBees, Inc.Online version published by CloudBees, Inc. under the Creative Commons Attribution-ShareAlike 4.0 license.CloudBees and CloudBees DevOptics are registered trademarks and CloudBees Core, CloudBees Flow, CloudBees Flow Deploy, CloudBees Flow DevOps Insight, CloudBees Flow DevOps Foresight, CloudBees Flow Release, CloudBees Accelerator, CloudBees Accelerator ElectricInsight, CloudBees Accelerator Electric Make, CloudBees CodeShip, CloudBees Jenkins Enterprise, CloudBees Jenkins Platform, CloudBees Jenkins Operations Center, and DEV@cloud are trademarks of CloudBees, Inc. Most CloudBees products are commonly referred to by their short names — Accelerator, Automation Platform, Flow, Deploy, Foresight, Release, Insight, and eMake — throughout various types of CloudBees product-specific documentation. Oracle and Java are registered trademarks of Oracle and/or its affiliates. Jenkins is a registered trademark of the non-profit Software in the Public Interest organization. Used with permission. See here for more info about the Jenkins project. The registered trademark Jenkins® is used pursuant to a sublicense from the Jenkins project and Software in the Public Interest, Inc. Read more at www.cloudbees.com/jenkins/about. Apache, Apache Ant, Apache Maven, Ant and Maven are trademarks of The Apache Software Foundation. Used with permission. No endorsement by The Apache Software Foundation is implied by the use of these marks.Other names may be trademarks of their respective owners. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this content, and CloudBees was aware of a trademark claim, the designations have been printed in caps or initial caps. While every precaution has been taken in the preparation of this content, the publisher and authors assume no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.