Submit Your Ideas

We want to hear from you - vote for the features and improvements you'd most like to see, or submit your own ideas if you don't find them already listed.

Matrix support in Workflows

It would be nice if there was more direct support in Workflows for spawning a matrix of builds for running tests using different environments, containers, etc.

Right now, even a simple matrix of tests requires something like this in config.yml:

version: 2

tox-job-template: &tox-job-template
steps:
- checkout
- run:
name: Unit tests
command: |
pip install tox
tox -e ${CIRCLE_JOB}

jobs:
py27-django18:
docker:
- image: python:2.7
<<: *tox-job-template

py27-django111:
  docker:
- image: python:2.7
<<: *tox-job-template

py36-django18:
  docker:
- image: python:3.6
<<: *tox-job-template

py36-django111:
  docker:
- image: python:3.6
<<: *tox-job-template

deploy:
...

workflows:
version: 2
build_and_deploy:
jobs:
- py27-django18
- py27-django111
- py36-django18
- py36-django111
- deploy:
requires:
- py27-django18
- py27-django18
- py36-django111
- py36-django111

Obviously, as more possibilities are added to the matrix, this quickly becomes unmanageable; for example, adding another version of Django would double the number of workflow jobs that need to be listed, both as jobs and as dependencies of the deploy job.

What would be nice is if instead we could do something like this:

version: 2

tox-job-template: &tox-job-template
steps:
- checkout
- run:
name: Unit tests
command: |
pip install tox
tox -e ${CIRCLE_MATRIX_JOB}

jobs:
template-py27:
docker:
- image: python:2.7
<<: *tox-job-template

template-py36:
docker:
- image: python:3.6
<<: *tox-job-template

deploy:
...

workflows:
version: 2
build_and_deploy:
jobs:
- test-matrix:
type: matrix
axes:
- python:
- py27
- py36
- django:
- django18
- django111
matrix_job_name: "{python}-{django}"
job: "template-{python}"
- deploy:
requires:
- test-matrix

This is a pretty basic example. The key ideas are:

  • In the "axes" section, you'd list each matrix axis, and then under each axis list each value that axis can take on.
  • This would generate a workflow job for every combination of values on each axis (in this case, there'd be four jobs, just like in the first example).
  • "matrix_job_name" would define a name that's passed to each job to identify which matrix element that job is running, using a simple substitution of the axis value for each axis name. This name would be passed into the job via an environment variable (I used CIRCLE_MATRIX_JOB here)
  • "job" would use the same substitution format as "matrix_job_name" to declare which actual job from the "jobs" section would be used to run a given matrix job, so that you can, for example, vary which Docker container is used, without having to have a separate job for every entry in the matrix.
  • In the "deploy" job, the requirement on "test-matrix" would force the "deploy" job to wait for every job in the matrix to succeed

A possible nice-to-have that I didn't show here would be an "exclude" entry in the matrix job that would allow you to exclude specific matrix jobs (perhaps based on the name generated by matrix-job-name), if for example you know you can't support some specific combination of Python and Django versions yet.

  • Avatar32.5fb70cce7410889e661286fd7f1897de Guest
  • Feb 8 2018
  • Future consideration
  • Attach files