💬

GitHub Actions とローカルの Node.js バージョンを一元管理する

2023/09/29に公開

実装

node-version の代わりに node-version-file を設定する。おわり。

jobs:
  ci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v3
        with:
          node-version-file: .tool-versions

      # ...

解説

私のローカル環境は複数バージョンの Node.js を切り替えるためのツールとして asdf を導入しています。asdf のバージョン管理ファイルは .tool-versions という名称で、これをリポジトリのルート直下に配置した状態でターミナルを開くと Node を指定されたバージョンへ自動的に切り替えてくれます。

.tool-versions
nodejs 18.18.0

さて、actions/setup-node にはバージョン指定の代わりにバージョン管理ファイルのパスを指定するオプションがあります。それが node-version-file です。
Advanced usage によると複数のバージョンマネージャーに対応しており、.nvmrc, .node-version, .tool-versions のほか、package.json も指定できるようです。

https://github.com/actions/setup-node/blob/main/docs/advanced-usage.md#node-version-file

先程のサンプルコードでは actions/setup-node を呼び出す step で node-version-file: .tool-versions というパラメーターを指定しています。
ワークフローの実行ログを見てみると、ファイルで指定したバージョンの Node を使ってくれているのがわかります。

Run actions/setup-node@v3
Node version file is not JSON file
Resolved .tool-versions as 18.18.0

Renovate を導入している環境においては、Node の新バージョンがリリースされた際に .tool-versions を更新する Pull Request が自動で作られ、同時に CI で自動的な検証を始められるので大変便利です。

おまけ: actions/setup-node から Node のバージョン文字列を取り出す

actions/setup-node は outputs を提供しており、実行した step からバージョン情報を取り出すことができます。バージョン管理ファイルを使いつつワークフロー内ではバージョン文字列も扱いたい、といったケースで活用できます。

https://github.com/actions/setup-node/blob/72c43c2d8fa01b0e1ca5fc3f8cb258c8d8bd286d/action.yml#L30-L34

step のデバッグログを見てみると v プレフィックス付きで出力されていました。

##[debug]Set output node-version = v18.18.0
##[debug]Finishing: Run actions/setup-node@v3

Node の メジャーバージョンを抜き出して actions/cache に設定する key の一部とする、みたいな使い方もできます。

jobs:
  ci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v3
        with:
          node-version-file: .tool-versions

      - id: setup-node
        uses: actions/setup-node@v3
        with:
          node-version-file: .tool-versions

      # バージョン文字列から最初のハイフン手前まで切り取る
      - run: NODE_MAJOR=$(echo $NODE_VERSION | cut -f 1 -d .) >> $GITHUB_ENV
        env:
          NODE_VERSION: ${{ steps.setup-node.outputs.node-version }}

      # `v18` と出力される
      - run: echo $NODE_MAJOR

      # ...

Discussion