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: 2tox-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: 2tox-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.
CCI-I-227