How can I configure a GitHub Actions strategy matrix to dynamically retrieve values from a JSON list based on user input? Below is the workflow I'm using:
name: Matrix team test
on:
workflow_dispatch:
inputs:
bosunEnvironment: # User Input Option - Will determine which bosun environment to build and deploy to.
description: 'Bosun Environment'
required: true
default: 'dev'
type: choice
options:
- 'dev'
- 'stg'
- 'prd'
stsReplay:
description: 'team to pick'
required: true
default: 'real-madrid'
type: choice
options:
- 'manu'
- 'chelsea'
- 'real-madrid'
- 'fc-barcelona'
- 'bayern'
- 'ac-milan'
env:
REPLAY_MAP_JSON: |
{
"manu": ["casemiro","dalot","rashford"],
"chelsea": ["sterling","james","silva"],
"real-madrid": ["vini-jr","modric","kroos"],
"bayern": ["sane","kane","alphonso"],
"ac-milan": ["rafael-leao","giroud","pulisic"]
}
jobs:
job1:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- id: set-matrix
run: |
input_replay="${{ inputs.stsReplay }}"
echo "input_replay: $input_replay"
values=$(jq -r ".\"${input_replay}\"[]" <<< "${REPLAY_MAP}")
echo "values: $values"
$values >> $GITHUB_OUTPUT
job2:
needs: job1
runs-on: ubuntu-latest
strategy:
matrix: ${{ fromJSON(needs.job1.outputs.matrix) }}
steps:
- run: echo "Player ${{ matrix}}"
I need the strategy matrix to behave as follows:
If the workflow_dispatch input is set to 'real-madrid', the strategy matrix should iterate over the list of players in the JSON value, which in this case is ["vini-jr","modric","kroos"].
Similarly, if the workflow_dispatch input is set to 'bayern', the strategy matrix should iterate over the list of players in the JSON value, which in this case is ["sane","kane","alphonso"].
Attempting to utilize a shell script as depicted earlier, the fromJSON() function failed to parse the list accurately.
Even after returning the entire JSON with values=$(echo "$REPLAY_MAP" | jq -r '.["'"$input_replay"'"]') >> $GITHUB_OUTPUT, the strategy matrix still did not interpret the JSON correctly.
There are different issues in your workflow:
1. You're not defining your output correctly on job1
, it should be echo "output_name=$values" >> $GITHUB_OUTPUT
2. Your parsing commands values=$(jq -r ".\"${input_replay}\"[]" <<< "${REPLAY_MAP}")
doesn't seem to work as expected. There are different ways to resolve it, I will suggest one below (it might not be the best one).
3. You are not using the matrix strategy correctly in your job2
, it should be:
strategy:
matrix:
player: ${{fromJson(needs.job1.outputs.matrix)}}
The following workflow configuration seems to work as expected:
jobs:
job1:
runs-on: ubuntu-latest
outputs:
players: ${{ steps.set-matrix.outputs.values }}
steps:
- id: set-matrix
run: |
input_replay="real-madrid"
echo "input_replay: $input_replay"
values=$(echo "${REPLAY_MAP_JSON}" | jq -r --arg input_replay "$input_replay" '.[$input_replay] | map("\"\(.)\"") | join(", ")')
echo "values:[$values]"
echo "values=[$values]" >> $GITHUB_OUTPUT
job2:
needs: job1
runs-on: ubuntu-latest
strategy:
matrix:
player: ${{fromJson(needs.job1.outputs.players)}}
steps:
- run: echo "Player ${{ matrix.player}}"