GitHub Actionsでの"Volta error: Could not unpack Node"に対処する

GitHub Actionsでの"Volta error: Could not unpack Node"に対処する

Clock Icon2024.09.17

はじめに

アノテーション LINE / DevOpsチームの草竹です。

Node.jsのバージョンマネージャーとして、 Volta を愛用しています。高速な動作やプロジェクト間の切替の手間のなさはありがたいですし、専用設定ファイルを必要とせずにpackage.jsonにプロジェクトのNode.jsバージョンを記述できるのがとても気に入っています。

GitHub Actionsにて volta-cli/action でNode.jsをインストールしている場合、Node.jsインストール時にエラーが発生することがありました。ワークフローを実行するたびに必ずしも発生せず、即座に再実行すると成功することはよくあります。

この記事では、GitHub Actionsにて表題のエラー Volta error: Could not unpack Node の原因とその解決策を紹介します。同様の事象に悩んでいる方の参考になれば幸いです。

事象の詳細

GitHub Actions ワークフローで、特定のタイミング(例えば、npm ci の実行時など)で次のエラーが発生し、ワークフローが失敗します。再実行すると成功することもありますが、続けて失敗することもあります。

実際に発生したエラーメッセージです。

Run npm ci
  npm ci
  shell: /usr/bin/bash -e {0}
  env:
    VOLTA_HOME: /opt/hostedtoolcache/volta/2.0.1/x64

Volta error: Could not unpack Node v20.12.1

Please ensure the correct version is specified.
Volta error: Error cause: failed to unpack `/opt/hostedtoolcache/volta/1.1.1/x64/tmp/.tmpCUWd0v/node-v20.12.1-linux-x64/bin/node`

Error cause: failed to unpack `/opt/hostedtoolcache/volta/1.1.1/x64/tmp/.tmpCUWd0v/node-v20.12.1-linux-x64/bin/node`

Error cause: failed to unpack `node-v20.12.1-linux-x64/bin/node` into `/opt/hostedtoolcache/volta/1.1.1/x64/tmp/.tmpCUWd0v/node-v20.12.1-linux-x64/bin/node`

Error cause: Resource temporarily unavailable (os error 11)
Error: Process completed with exit code 126.

原因と解決策

まずは、原因と解決策を簡単にご紹介します。

  • GitHub ActionsでNode.jsをインストールしようとした時、リポジトリのレート制限によりエラーが生じる可能性が指摘されています。

  • Node.jsのインストールに actions/setup-node を用いることで、レート制限を緩和できると考えられます。なお、Node.jsバージョンの参照先にpackage.json内の volta.node の記述を利用することができるため、開発環境でのVolta利用と引き続き連携することが可能です。

以降、調査の過程と具体的な解決策を紹介します。

調査の過程

まず、Volta は volta-cli/actions@v4 によって GitHub Actions のランナーにインストールされています。このエラーの原因を調査するために、以下の点を確認しました。

  • Volta本体やActionリポジトリで報告されているIssueを調査
  • CI環境やVPN環境で同様のエラーが発生している事例を確認

次のIssueが詳しいです。

https://github.com/volta-cli/volta/issues/1523

ここでは、CI 環境や VPN 環境で同様のエラーが発生している報告が多く見られました。特に、GitHub Actions から Node.js リポジトリへのリクエストが、レート制限[1]によって拒否されている可能性が指摘されています。

GitHub Actions や VPN 下では、複数ユーザーが同一のIPアドレスを共有した状態です。多くのリクエストが短期間に同一IPアドレスから送信された場合、DDoS攻撃などのセキュリティ的懸念から、単位時間あたりの回数上限を超過したリクエストがレート制限によりブロックされることがあります。

Volta 側でも、Node.js のミラーサーバーを利用するなどのフォールバック対応が議論されています[2]が、現時点では正式な解決策は提供されていません。(どの環境でも同じツールを利用したまま解決できればうれしいですよね!)

解決策

解決策のポイントは3つです。

  • 開発環境では引き続きVoltaを使用します。
  • GitHub Actionsでは actions/setup-node を使います。
  • package.json 内の volta.node を参照して、開発環境とGitHub Actionsで同じNode.jsバージョンをインストールします。

Node.jsのバージョン管理ツールに開発環境ではVoltaを使い、GitHub Actions では actions/setup-node を使う選択をしました。

actions/setup-node は、package.json 内の volta.node を参照し、指定されたバージョンの Node.js をインストールすることができます。これにより、開発環境で Volta を使っている場合でも、GitHub Actions 上では同じバージョンの Node.js を使用することができ、環境の一貫性が保たれます。

sample-workflow.yml
steps:
- uses: actions/setup-node@v4
  with:
    node-version-file: 'package.json'
- run: npm ci

参考:

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

また、 actions/setup-node はローカルキャッシュ、actions/node-versions、Node.jsリポジトリのディストリビューション という順番に取得する戦略をとっているため、Node.jsリポジトリのレート制限に拒否されるシナリオを減らすことができます。

最終的には次のコードになりました。

build-example.yml
jobs:
  build:
    runs-on: ubuntu-latest
    name: Build example
    steps:
+      - uses: actions/setup-node@v4
+        with:
+          node-version-file: 'package.json'
-      - uses: volta-cli/action@v4
package.json
{
  "volta": {
    "node": "20.17.0"
  }
}

まとめ

  • GitHub ActionsでVoltaを使っている際に発生するエラーは、レート制限などのネットワーク関連の問題が原因であることが多いです。
  • actions/setup-node を使い、package.json の volta.node を参照することで、ワークフローの信頼性を向上させることができます。
  • この解決策により、レート制限の影響を軽減しつつ、開発環境とGitHub Actionsで同じNode.jsバージョンを使用することが可能です。

Volta側での解決策が提供されるまで、この方法が効果的な解決策だと考えられます。

脚注
  1. Rate Limitingとは?|Rate Limitingとボット | Cloudflare ↩︎

  2. Feature Request: Use Node.js mirror fallbacks for downloads · Issue #1887 · volta-cli/volta ↩︎

この記事をシェアする

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.