😽

GitHub Actions で言語のバージョンをファイルから読み出す

2022/02/14に公開1

皆さん、プロジェクトの言語ランタイムのバージョン固定してますか?僕はしてます。

Node.js や Ruby 、Python などの処理系をお使いの方は特に言語のバージョンを固定する術を過去いくつも試し、戦い、そして打ち勝ってきたことかと存じます。

そんな僕らのバージョン固定大会における GitHub Actions 攻略方法を編み出したのでご笑覧ください。

根本的には .lang-version を見てほしい

.ruby-version で Ruby のバージョンを指定しているのに、ruby.yml でも ruby/setup-ruby でバージョンが書かれており無念です。なので、 .ruby-version での管理に一本化します。

ruby.yml
jobs:
  ruby-test-action:
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Detect ruby version
        id: ruby-version
        run: echo "::set-output name=VERSION::$(cat .ruby-version)"
      - name: Setup ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: '${{ steps.ruby-version.outputs.VERSION }}'

大事な点は Detect ruby version を必ず Checkout の後に実行することです。じゃないと .ruby-version はどこ探しても見当たらないので。

これは大抵どの言語でも通用します。

actions.yml
jobs:
  node-test-action:
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Detect node version
        id: node-version
        run: echo "::set-output name=VERSION::$(cat .node-version)"
      - name: Setup node
        uses: actions/setup-node@v2
        with:
          node-version: '${{ steps.node-version.outputs.VERSION }}'

  go-test-action:
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Detect go version
        id: go-version
        run: echo "::set-output name=VERSION::$(cat .go-version)"
      - name: Setup go
        uses: actions/setup-go@v2
        with:
          go-version: '${{ steps.go-version.outputs.VERSION }}'

めっちゃかんたんな割に案外使いまわしの効く方法なのでめちゃんこ気に入っています。

これ、例えば Dockerfile をこんな具合に書いておくと

ruby.dockerfile
ARG RUBY_VERSION=3.0.0
FROM ruby:$RUBY_VERSION

GitHub Actions での build 時にこんな具合にリポジトリの .ruby-version の内容が渡せます。

ruby-and-docker.yml
jobs:
  ruby-test-action:
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Detect ruby version
        id: ruby-version
        run: echo "::set-output name=VERSION::$(cat .ruby-version)"
      - name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          build-args: |
            RUBY_VERSION=${{ steps.ruby-version.outputs.VERSION }}

1ファイル管理最高!!!!!ついでに .ruby-version で一括管理していると dependabot などがよきにバージョンをあげてくれて、マージボタンを押すだけでランタイムのバージョンアップできるようになったりするので、大変体験がいいです。でべのえくすのぺりや。

ということで、ちょっと便利 Tips でした。

Discussion

hogefugatmphogefugatmp

Detect node version等はなしでも恐らくnode-version-fileで直接ファイルを読めるかと。
pythonでは下記で読めました。

            - name: Setup Python 3.10
              uses: actions/setup-python@v5
              with:
                python-version-file: .python-version