GitHub Actionsのmatrixを動的に生成してGoの最新安定バージョンでテストする
Goのライブラリを提供している場合、Goの最新の安定バージョンでテストしたくなることがあるでしょう。具体的にはマイナーバージョンの直近2バージョン、今だと1.18と1.17です。GitHub Actions定義への記述は以下のようになるでしょう。
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
go-version: ['1.17', '1.18']
steps:
- uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
- run: go test ./...
しかしこのようにベタに書いてしまうと、Goのバージョンが上がったときにチマチマ上げるのが地味にめんどくさい。なのでこれを動的に生成したい。
これは事前にGoの安定バージョン一覧を取得するjobを走らせ、その出力からmatrix用のリストを生成すれば実現できます。具体的には以下のようにした。
jobs:
go-versions:
runs-on: ubuntu-latest
outputs:
versions: ${{ steps.versions.outputs.value }}
steps:
- id: versions
run: |
versions=$(curl -s 'https://go.dev/dl/?mode=json' | jq -c 'map(.version[2:])')
echo "::set-output name=value::${versions}"
test:
needs: go-versions
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
go-version: ${{fromJson(needs.go-versions.outputs.versions)}}
steps:
- uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
- run: go test ./...
go-versions
というジョブで https://go.dev/dl/?mode=json からGoの安定バージョン一覧を取得してそれをjq
で加工し、GitHub Actionsのset-output
で出力を作っている。
% curl -s 'https://go.dev/dl/?mode=json' | jq -c 'map(.version[2:])'
["1.18.2","1.17.10"]
その出力を test
ジョブの中で使っているという具合。test.needs
に go-versions
を依存として記述している。
実際に拙作の prompter というライブラリに 導入してみた がちゃんと動いている。
本当はカスタムアクションを提供できると嬉しいと思ったのだが、一旦このような形でささっとやってみた。
https://go.dev/dl/?mode=json は決め打ちで最新安定のマイナー2バージョンしか返さない。それで多くの場合は十分だろうが、例えば3バージョンテストしたいとか、次バージョンのRCが出たらそれも早めにテストしたいなどのニーズもあろうかと思う。
その場合は、 https://go.dev/dl/?mode=json&include=all から一覧を取得してテストしたいバージョンを抜き出せると嬉しそうである。
そういった機構も含めたカスタムアクションがあると良さそうなので、僕もそのうち気が向いたらやるかも知れないが、誰かチャレンジしてくれると嬉しい。