A reusable workflow for loading a job's matrix strategy from a JSON configuration file.
See matrix-config.yml.
Here's a basic example of how to load a matrix strategy from a config file.
Define your matrix strategy in a config file.
{
"include": [
{
"label": "My first item",
"server-name": "host01",
"enable": true
},
{
"label": "My second item",
"server-name": "host02",
"enable": true
},
{
"label": "I am configured, but not enabled. I will not be run.",
"server-name": "host03",
"enable": false
}
]
}
JSON comments (or JSONC) are fully supported in config files.All comments are stripped before parsing.
Important
GitHub only allows matrix configurations to be two-levels deep.
Meaning, any item within the include
array cannot have a value that is an
object literal, or array.
For more information on configuring matrix strategies, see GitHub's documentation.
Here's how you'll setup your job to call the matrix config reusable workflow, and load the configuration into your matrix strategy.
jobs:
load-matrix:
name: Load matrix
uses: jonlabelle/matrix-workflow-config/.github/workflows/matrix-config.yml@main
with:
config: ./.github/matrix-config/example.json
use-matrix:
name: Use matrix on ${{ matrix.server-name }}
needs: [load-matrix]
runs-on: ubuntu-latest
strategy:
matrix: ${{ fromJson(needs.load-matrix.outputs.matrix) }}
steps:
- name: ${{ matrix.label }}
if: ${{ matrix.enable }}
run: |
echo "Server: ${{ matrix.server-name }}"
You can extend your matrix config (at runtime) by passing in additional
key-value pairs that will bind to each item in the include
array.
Note
You can run this example from the actions section of this repo.
Here, we'll extend our config using the
extend
key,'{ "existing-key": "overridden by extend input option", "prop2": "value2", "prop3": 3 }'
.
jobs:
load-matrix:
name: Load matrix
uses: ./.github/workflows/matrix-config.yml
# Use the following path when calling from your own repo/workflow
# uses: jonlabelle/matrix-workflow-config/.github/workflows/matrix-config.yml@main
needs: [show-matrix-config-file]
with:
config: ./.github/matrix-config/example.json
# Additional key/value pairs to bind to each item in matrix config's `include` array.
# If a key already exists, its value will be overwritten (for each item in the include array).
extend: '{ "existing-key": "overridden by extend input option", "prop2": "value2", "prop3": 3 }'
# If the provided value for extend is a flat array (e.g. '["one", "two", "three"]'),
# then the matrix is also assumed to be a flat array, and the new values will simply
# be appended to the existed matrix array.
# extend: '["one", "two", "three"]'
use-matrix:
name: Use matrix on ${{ matrix.server-name }}
needs: [show-matrix-config-file, load-matrix]
runs-on: [self-hosted, Linux, X64, onprem, enterprise]
strategy:
matrix: ${{ fromJson(needs.load-matrix.outputs.matrix) }}
steps:
- name: Show extended matrix config json
if: ${{ matrix.enable }}
run: echo '${{ needs.load-matrix.outputs.matrix }}' | jq '.' --color-output
Original matrix json config file contents.
{
"include": [
{
"label": "My first item",
"server-name": "host01",
"enable": true,
"existing-key": "this value will be overridden by a value defined in the extend input option."
},
{
"label": "My second item",
"server-name": "host02",
"enable": true,
"existing-key": "this value will be overridden by a value defined in the extend input option."
},
{
"label": "I am configured, but not enabled. I will not be run.",
"server-name": "host03",
"enable": false,
"existing-key": "this value will be overridden by a value defined in the extend input option."
}
]
}
Matrix json config after extending.
{
"include": [
{
"label": "My first item",
"server-name": "host01",
"enable": true,
"existing-key": "overridden by extend input option",
"prop2": "value2",
"prop3": 3
},
{
"label": "My second item",
"server-name": "host02",
"enable": true,
"existing-key": "overridden by extend input option",
"prop2": "value2",
"prop3": 3
},
{
"label": "I am configured, but not enabled. I will not be run.",
"server-name": "host03",
"enable": false,
"existing-key": "overridden by extend input option",
"prop2": "value2",
"prop3": 3
}
]
}