Github Actions - Matrix Build with sequential deployments!

Intro

Github Actions Matrix Builds are a powerful way to parallelize build steps and thus significantly improve feedback loops in the CI pipeline. But did you know that you can use Matrix Builds not only for parallel build steps, but also for sequential ones?

This can save many lines of YAML, as long as the build steps are the same for all stages. As soon as one of the steps from the previous workflow fails, the whole pipeline will fail.

Example

The trick is to use a matrix build, limit concurrent executions to one and set fail-fast (to fail the whole workflow when a single step fails) to roll out deployments to stages (for example development, integration, production, …)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
...
jobs:
  deploy:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        stage: ['development', 'integration', 'production']
      fail-fast: true
      max-parallel: 1
    steps:
      - name: do some stuff
        uses: ...
        with: ...

all the magic happens here:

1
2
3
4
5
6
matrix:
    stage: ['development', 'integration', 'production']
# When set to true, GitHub cancels all in-progress jobs if any matrix job fails.
fail-fast: true
# The maximum number of jobs that can run simultaneously
max-parallel: 1

It will be even cooler if we additionally use Github environments, for example to use stage specific credentials or secrets for each workflow run.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
jobs:
  deploy:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        stage: ['development', 'integration', 'production']
      fail-fast: true
      max-parallel: 1
    # set the environment to use (environment must exist and be named the same as the stage here)
    environment:
      name: ${{ matrix.stage }}
    steps:
    # use environment specific secrets here for each stage
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-session-token: ${{ secrets.AWS_SESSION_TOKEN }}
          aws-region: wonderland-central-1
      - name: do some stuff
        uses: ...
        with: ...

Not only are the individual matrix builds executed sequentially, but also the secrets (here for example for AWS STS) for the respective stage are obtained from the environments! That means the workflow does not change, because the build steps are the same. But they are parameterized differently by the Secrets depending on the Matrix Build from the Environments.

And that’s it for today!