GitHub Actionsの再利用可能なワークフローに,入力として別YAMLファイルで指定したmatrixを与える方法について,苦心の末,ようやく実現できましたので,ご報告します.
ElixirとErlang/OTPのバージョンのmatrixを与える場合を例に書きます.
matrixの与え方
通常のmatrixだと次のように与える場合について,
- otp-version: ['24.3.4.13', '25.3.2.3', '26.0.2']
elixir-version: ['1.14.5', '1.15.4']
次のように展開し,さらにinclude:
の下につけます.エラーにならないよう,.github/workflows
とは別のディレクトリに配置することもポイントです.
include:
- otp-version: '24.3.4.13'
elixir-version: '1.14.5'
- otp-version: '24.3.4.13'
elixir-version: '1.15.4'
- otp-version: '25.3.2.3'
elixir-version: '1.14.5'
- otp-version: '25.3.2.3'
elixir-version: '1.15.4'
- otp-version: '26.0.2'
elixir-version: '1.14.5'
- otp-version: '26.0.2'
elixir-version: '1.15.4'
再利用可能なワークフローの書き方
次のようにします.
name: Reusable workflow
on:
workflow_call:
inputs:
matrix:
required: true
type: string
jobs:
reusable_ci:
name: On ${{ matrix.elixir-version }}, ${{ matrix.otp-version }}
runs-on: ubuntu-latest
strategy:
matrix: ${{ fromJSON(inputs.matrix) }}
steps:
- run: echo "done."
fromJSON
を用いることがポイントです.
呼び出し側
次のようにします.
name: Caller CI
on:
pull_request:
types: [opened, reopened, synchronize]
branches: [ "main", "develop" ]
push:
branches: [ "main", "develop" ]
jobs:
constants:
name: Constants
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v3
- id: set-matrix
run: |
json=$(cat ${{ github.workspace }}/.github/actions/matrix.yml| ruby -ryaml -rjson -e 'puts YAML.load(STDIN).to_json')
echo "matrix=${json}" >> $GITHUB_OUTPUT
call_reusable_workflows:
name: Call Reusable Workflows
needs: constants
uses: ./.github/workflows/reusable_ci.yml
with:
matrix: ${{ needs.constants.outputs.matrix }}
あらかじめ,id: set-matrix
としておきます.
YAMLからJSONへの変換のRubyワンライナーcat file.yml| ruby -ryaml -rjson -e 'puts YAML.load(STDIN).to_json'
がポイントです.これで1行のJSONで出力されます. (Thanks! @zumin )
その値を環境変数json
に一旦格納し,echo "matrix=${json}" >> $GITHUB_OUTPUT
とすることで,matrix
変数への出力として格納します.
それを matrix: ${{ steps.set-matrix.outputs.matrix }}
として出力されたmatrix
の値を参照したものを,matrix
に入れます.
それをその後の呼び出しで,with: matrix: ${{ needs.constants.outputs.matrix }}
として,再利用可能なワークフローに渡します.