おそらくはそれさえも平凡な日々

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.needsgo-versions を依存として記述している。

ref. https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter

実際に拙作の prompter というライブラリに 導入してみた がちゃんと動いている。

本当はカスタムアクションを提供できると嬉しいと思ったのだが、一旦このような形でささっとやってみた。

https://go.dev/dl/?mode=json は決め打ちで最新安定のマイナー2バージョンしか返さない。それで多くの場合は十分だろうが、例えば3バージョンテストしたいとか、次バージョンのRCが出たらそれも早めにテストしたいなどのニーズもあろうかと思う。

その場合は、 https://go.dev/dl/?mode=json&include=all から一覧を取得してテストしたいバージョンを抜き出せると嬉しそうである。

そういった機構も含めたカスタムアクションがあると良さそうなので、僕もそのうち気が向いたらやるかも知れないが、誰かチャレンジしてくれると嬉しい。

created at
last modified at
comments powered by Disqus