-
Notifications
You must be signed in to change notification settings - Fork 45
Matrix job support
The concept of a matrix job is to test multiple types of similar technologies across different builds. Matrix builds are independent of each other so are run in parallel. For example, one might want to build their project testing across multiple versions of Java. Jervis builds against multiple versions of Groovy for backwards compatibility with older versions of Jenkins.
- Environment matrix (also explains one dimensional matrix)
- Multidimensional matrix builds allow N-dimensional matrices to build across multiple versions of multiple technologies.
-
Matrix filtering filters specific matrix axes to be
built.
- Filter by exclude filters buildable matrix axes with exclude rules.
- Filter by include filters buildable matrix axes with include rules.
- Matrix support by language documents additional matrix building support provided by specific languages referring to which tools are typically customized for that language.
- Matrix support by tool documents a comprehensive list of tools supported for matrix building.
Every project type has available to it the env YAML key. It's what Jervis
uses to test multiple versions of Groovy. Travis CI also
supports environment matrix. This allows launching similar
builds with different sets of environment variables.
A simple one dimentional matrix can be tested with a list in the env key.
env:
- ANIMAL=cat VEHICLE=bike_basket
- ANIMAL=dog VEHICLE=carWill execute two matrix builds in parallel. The first build will have
environment variables ANIMAL=cat and VEHICLE=bike_basket set. The other
build will have ANIMAL=dog and VEHICLE=car. Each build is called a matrix
axis.
Sometimes, it is desireable to share environment variables across matrix axes.
The following syntax is also supported for the env key. To run the same
matrix builds above but share an environment variable across all matrix axes,
the following syntax is support.
env:
global:
- DRIVER=person
matrix:
- ANIMAL=cat VEHICLE=bike_basket
- ANIMAL=dog VEHICLE=carWill execute two matrix builds in parallel. The first build will have
environment variables ANIMAL=cat, VEHICLE=bike_basket, and DRIVER=person
set. The other build will have ANIMAL=dog, VEHICLE=car, and
DRIVER=person. In this case, DRIVER=person is shared across all buildable
matrix axes.
To build multidimensional matrices you need to define matrix builds across
multiple YAML keys. For example, Java supports matrix building for the
env and jdk YAML key. Let's build a 2 dimensional matrix testing different
environment configurations testing across multiple Java JDKs.
language: java
env:
- DATABASE=mysql
- DATABASE=postgres
- DATABASE=sqlite
jdk:
- openjdk7
- openjdk8The above will launch 6 matrix axis builds in parallel (a 2 dimensional 3x2 matrix) in order to test every possible combination.
Buildable matrix axes (6 builds in parallel):
-
env: DATABASE=mysql,jdk: openjdk7 -
env: DATABASE=postgres,jdk: openjdk7 -
env: DATABASE=sqlite,jdk: openjdk7 -
env: DATABASE=mysql,jdk: openjdk8 -
env: DATABASE=postgres,jdk: openjdk8 -
env: DATABASE=sqlite,jdk: openjdk8
A rule of thumb for calculating matrix building: for every YAML key which supports matrix building is an additional dimension possible for matrix building. Mathematically multiply together the number of values in each dimension to get the total possible builds run in parallel.
For example, the Ruby language supports env, rvm, gemfile, and
jdk. In Ruby, it's possible to have a 4 dimensional matrix build.
With N-dimensional matrices in a build it is sometimes desirable to only build some matrix axis combinations and not others. Matrix filtering support allows developers to build only the matrix axes they need.
There are two ways to filter matrix axes. Filtering by include (whitelist) or filtering by exclude (blacklist). Filtering by include and exclude can be done at the same time. However, exclusion takes precedence over inclusion. That is, if an exclude filter matches a matrix axis then that axis will not be built regardless of include matching it.
Take for example this 3 dimensional matrix in ruby (4x3x4 matrix with maximum 48 buildable axes). In the following example, changing Java versions for MRI ruby doesn't make sense because it is not Java based. It should be excluded. After filtering there will only be 36 buildable axes.
language: ruby
rvm:
- 1.9.2
- jruby-18mode
- jruby-19mode
- jruby-head
jdk:
- openjdk6
- openjdk7
- oraclejdk7
gemfile:
- Gemfile
- gemfiles/rails4.gemfile
- gemfiles/rails31.gemfile
- gemfiles/rails32.gemfile
matrix:
exclude:
- rvm: 1.9.2
jdk: openjdk6
- rvm: 1.9.2
jdk: openjdk7
- rvm: 1.9.2
jdk: oraclejdk7Shorthand exclusion is also possible. The following is an example of excluding
all matrix indices which have rvm: 2.0.0 and gemfile: Gemfile no matter what
other matrix dimension exists. The following filters down to 45 buildable
matrix axes.
matrix:
exclude:
- rvm: 1.9.2
gemfile: GemfileFiltering by include is a way to whitelist building matrix axes. Take the
following example which is meant to be paired with the ruby example at the top
of the Filter by exclude section.
matrix:
exclude:
- rvm: 1.9.2
gemfile: Gemfile
include:
- rvm: 1.9.2include adds to the exclude filter combining into a more comprehensive
filter. The example above shows an exclude for rvm: 1.9.2 and gemfile: Gemfile. However, the include states rvm: 1.9.2. This means it will run
only rvm: 1.9.2 (include) matrices except for when gemfile: Gemfile is
matched (exclude). Put another way it can be thought of as the following groovy
filter.
!(rvm == "1.9.2" && gemfile == "Gemfile") && (rvm == "1.9.2")A thorough explanation and example is provided in this comment and this comment of issue #7.
This feature is not currently supported.
allow_failures has not been implemented in the matrix
build plugin. There is an open feature request for matrixy project type
JENKINS-26188 hoping to address this.
As pipeline support for Jervis expands, setting an unstable result for a buildable axis will be researched as an allowed failure rather than failing the whole pipeline.
This section includes quick links to languages and their matrix support. The languages only document tools typically customized for the build matrix of that language.
Note: other tool matrices not listed for the language can be specified as an additional matrix for a project. Large projects tend to consist of many languages, technologies, and stacks. Therefore, any tool can be grouped with any language. These are just common groupings. See Matrix support by tool for a comprehensive list of known supported tools.
Fully supported languages (code and wiki docs):
Nearly finished support (code but no wiki docs):
Unfinished support (no/some code and no wiki docs):
For Android projects,
env and jdk can be given as arrays to construct a build
matrix.
For C projects, env and
compiler can be given as arrays to construct a build matrix.
For C++ projects, env
and compiler can be given as arrays to construct a build matrix.
For Clojure projects,
env, lein, and jdk can be given as arrays to construct a
build matrix.
TODO: research
leinmatrix support.
C# projects do not appear to have a matrix build currently.
For D projects, env and
d can be given as arrays to construct a build matrix.
TODO: research
dmatrix support.
For Erlang projects,
env and otp_release can be given as arrays to construct a build
matrix.
TODO: research
otp_releasematrix support.
F# projects do not appear to have a matrix build currently.
For Go projects, env
and go can be given as arrays to construct a build matrix.
TODO: research
gomatrix support.
For Groovy projects,
env and jdk can be given as arrays to construct a build
matrix.
For Haskell projects,
env and ghc can be given as arrays to construct a build matrix.
TODO: research
ghcmatrix support.
For Java projects,
env and jdk can be given as arrays to construct a build
matrix.
For JavaScript/Node.js projects, env and node_js can be
given as arrays to construct a build matrix.
TODO: research
node_jsmatrix support.
For Julia projects,
env and julia can be given as arrays to construct a build matrix.
TODO: research
juliamatrix support.
For Objective-C projects, env, rvm,
gemfile, xcode_sdk, and xcode_scheme can be given as arrays to
construct a build matrix.
TODO: research
xcode_sdkandxcode_schemematrix support.
For Perl projects,
env and perl can be given as arrays to construct a build matrix.
TODO: research
perlmatrix support.
For PHP projects, env
and php can be given as arrays to construct a build matrix.
TODO: research
phpmatrix support.
For Python projects,
env and python can be given as arrays to construct a
build matrix.
For Ruby projects,
env, rvm, gemfile, and jdk can be
given as arrays to construct a build matrix.
Rust projects do not appear to have a matrix build currently.
For Scala projects,
env, scala, and jdk can be given as arrays to construct a
build matrix.
TODO: research
scalamatrix support.
Is a basic and empty language type defined to run scripts in the default shell
of any selected platform and operating system. env can be given an
array to construct a build matrix.
Visual Basic projects do not appear to have a matrix build currently.
The following documents matrix support by tool. In a language, multiple tools may be involved with building or testing that technology. The use of chaining tools for a particular language is called a toolchain.
Testing against two compilers will create (at least) 2 rows in your build matrix. e.g.
compiler:
- clang
- gcc
env support is documented at the top of this page under Environment
matrix.
Ruby can be built against multiple Gemfiles. It is useful to do this to test multiple versions of dependencies for your project (for example multiple rails versions).
language: ruby
gemfile:
- Gemfile
- gemfiles/rails4.gemfile
- gemfiles/rails31.gemfile
- gemfiles/rails32.gemfileWill execute at least four matrix builds.
Testing with multiple JDKs. To test against OpenJDK 7 and OpenJDK 6:
jdk:
- openjdk7
- openjdk6
Virtualenv is what supports multiple
versions of Python. By default builds will be run with Python 2.7. You can
specify a version of Python using the python key in .jervis.yml.
python: "3.2"To build against multiple versions of Python in a matrix build use a list.
python:
- "2.6"
- "2.7"RVM is what supports multiple versions of Ruby in Jervis.
language: ruby
rvm:
- 1.9.3
- jruby-18mode # JRuby in 1.8 mode
- jruby-19mode # JRuby in 1.9 mode
- rbx-2.1.1
- 1.8.7Will execute at least five matrix builds. One for each version of ruby known to RVM. If a version of ruby is not installed then it will be installed automatically.
- Build overview
- Supported languages
- Supported build tools
- Publish results
- Additional topics:
- Quickstart
- Background information
- Knowledge checklist
- Required Jenkins Plugins
- Labels for Jenkins Agents
- Key security concepts
- Operationalize Jenkins
- High availability
- Disaster recovery
- Pipeline support
- Extending support