こんにちは。ブロックチェーンチームのソフトウェアエンジニアの id:odan3240 です。
下記の記事で紹介した通り、ブロックチェーンチームではバックエンドでも Node.js を使用しています。 tech.mobilefactory.jp
フロントエンドとバックエンドのソースコードは同一リポジトリで管理するモノレポを採用しています。
使用しているライブラリやプラットフォームの違いもあり、フロントエンドとバックエンドでは異なる Node.js のバージョンを使用しています。複数のバージョンを使い分けるために開発環境では nodenv を導入しています。
この記事ではチームで実践している GitHub Actions で nodenv を使用して複数の Node.js のバージョンを使い分ける方法を紹介します。
公式の Actions はあるが Node.js のインストールは行われない
nodenv の Organization が Actions を公開しています。
これを使えばバージョンの使い分けができるように見えます。しかしこの Actions は nodenv コマンドをインストールするだけで、その先の環境の設定や指定したバージョンの Node.js のインストールは自分で行う必要があります。
setup-node だと Node.js のバージョンの切り替えができない
GitHub Actions で Node.js のインストールというと setup-node を思い浮かべる人が多いでしょう。
しかしこの Actions は一時的に PATH に含まれる node コマンドを置き換えるだけです。nodenv の機能にある、都度ローカルの .node-version
ファイルを読んでバージョンの違う node コマンドを実行できるようにはなりません。
そのため今回のようなディレクトリごとに Node.js のバージョンを切り替えたい要求には使用することができません。
解決策
今回は次の Actions を書いて問題を解決しました。今回のサンプルコードは GitHub に置いてあります。
重要なステップを1つずつ説明していきます。
name: CI on: push: branches: [ "main" ] pull_request: branches: [ "main" ] workflow_dispatch: jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: nodenv/actions/setup-nodenv@v2 - name: Install node-build run: | mkdir -p "$(nodenv root)"/plugins git clone https://github.com/nodenv/node-build.git "$(nodenv root)"/plugins/node-build - name: Install node run: nodenv install -s - name: Run nodenv init run: | echo "$(nodenv root)"/shims >> $GITHUB_PATH echo "NODENV_SHELL=bash" >> $GITHUB_ENV nodenv rehash - name: Check node version run: node -v
Install node-build
について
nodenv だけでは Node.js のインストールができないため node-build を別途インストールする必要があります。
node-build の README で説明されている通り nodenv のプラグインとしてインストールしています。
Run nodenv init
について
nodenv init 相当のセットアップを行っています。
開発環境に nodenv をインストールする場合、eval "$(nodenv init -)"
を実行するか .bashrc
や .zshrc
に eval "$(nodenv init -)"
を追記する必要があります。self-hosted not using bashrc · Discussion #25407 · community を参考に .bashrc
に追記する方法も試してみましたが環境変数が設定されませんでした。
これは、GitHub Actions では変数を export しても環境変数として扱われないことが原因だと予想して、手動で設定する方針にしました。
GitHub Actions 上で nodenv init
を実行したときの出力内容は次の通りです。
export PATH="/home/runner/.nodenv/shims:${PATH}" export NODENV_SHELL=bash source '/opt/hostedtoolcache/nodenv/1.3.1/x64/libexec/../completions/nodenv.bash' command nodenv rehash 2>/dev/null nodenv() { local command command="${1:-}" if [ "$#" -gt 0 ]; then shift fi case "$command" in rehash|shell) eval "$(nodenv "sh-$command" "$@")";; *) command nodenv "$command" "$@";; esac }
これに相当することを GitHub Actions 流の設定方法で step に記述しています。
これらの対応を行うことで、GitHub Actions でも cd すると自動的に .node-version
の Node.js が実行されるようになります。
まとめ
- ブロックチェーンチームではモノレポでディレクトリごとに異なる Node.js のバージョンを使用している
- 開発環境と同様に GitHub Actions でも nodenv で Node.js を使い分けたくなった
nodenv/actions/setup-nodenv
やactions/setup-node
では目的を達成できないnodenv init
の内容に相当する処理を step に書くと、自動的に Node.js のバージョンが切り替わるようになる