Overview
This blog post demonstrates how to set up a GitHub Actions workflow that uses a dynamic matrix strategy based on configurations stored in an external JSON file. This approach allows you to define multiple job configurations outside of your main workflow file, promoting reusability and maintainability.
Explanation with Inline Comments
jobs:
# Job to prepare the matrix configuration from an external JSON file
prepare-matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }} # Output the matrix to be used by other jobs
steps:
- uses: actions/checkout@v2 # Checks out your repository under $GITHUB_WORKSPACE
- id: set-matrix
run: |
# Using jq to parse the matrix-config.json file and convert it to a compact JSON string
MATRIX_JSON=$(jq -c . < ./matrix-config.json)
# Echo the matrix JSON into the GitHub Actions output variable
echo "matrix=${MATRIX_JSON}" >> $GITHUB_OUTPUT
# Deployment job that uses the matrix prepared in the prepare-matrix job
deploy:
needs: prepare-matrix # Indicates that this job needs the output of prepare-matrix
runs-on: ubuntu-latest
strategy:
fail-fast: false # Disable fail-fast to continue other matrix jobs even if one fails
matrix: ${{fromJson(needs.prepare-matrix.outputs.matrix)}} # Parse JSON output to matrix
steps:
- name: test
run: |
# Print the first name (fname) from the matrix configuration to demonstrate usage
echo ${{ matrix.fname }}
{
"include": [
// Each object in this array represents a different configuration for the matrix
{"fname": "f name 1", "lname": "l name 1"},
{"fname": "f name 2", "lname": "l name 2"},
{"fname": "f name 3", "lname": "l name 3"},
{"fname": "f name 4", "lname": "l name 4"}
]
}
Defining a Matrix Configuration
Let’s start by defining a matrix configuration in an external JSON file named matrix-config.json
. Each object in the JSON array represents a different configuration for the matrix.
{
"include": [
{"fname": "f name 1", "lname": "l name 1"},
{"fname": "f name 2", "lname": "l name 2"},
{"fname": "f name 3", "lname": "l name 3"},
{"fname": "f name 4", "lname": "l name 4"}
]
}
Generating Matrix Configurations
Next, we’ll create a GitHub Actions workflow that prepares the matrix configuration from the matrix-config.json
file. The prepare-matrix
job will parse the JSON file using jq
and output the matrix to be used by other jobs.
jobs:
prepare-matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v2
- id: set-matrix
run: |
MATRIX_JSON=$(jq -c . < ./matrix-config.json)
echo "matrix=${MATRIX_JSON}" >> $GITHUB_OUTPUT
Using Matrix Configurations
Finally, we’ll create a deploy
job that utilizes the matrix prepared in the prepare-matrix
job. By specifying needs: prepare-matrix
, we ensure that this job waits for the matrix to be generated before executing. The matrix is parsed from the JSON output using ${{fromJson(needs.prepare-matrix.outputs.matrix)}}
.
deploy:
needs: prepare-matrix
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix: ${{fromJson(needs.prepare-matrix.outputs.matrix)}}
steps:
- name: test
run: |
echo ${{ matrix.fname }}