メインコンテンツへスキップ
ブログサイトのロゴsui Tech Blog
5分で読めます

pnpm のセットアップに 7 分かかっていたので pnpm/setup へ移行した

GitHub Actions で pnpm v11 を pnpm/action-setup で入れていたら、セットアップ step だけで 7 分かかっていました。pnpm v11 以降で使える pnpm/setup へ差し替える手順と、移行時に引っかかる pnpm install の扱い、pnpm v10 以前が対象外である点までを紹介します。

GitHub Actions で pnpm を使うとき、pnpm/action-setup で pnpm を入れて actions/setup-node で Node.js を入れる、という 2 つの step を並べる書き方が長く定番でした。CI が遅いと感じたときに疑うのも、たいていはテストやビルドです。セットアップ step にかかった時間をログで確認する機会は、あまりありません。

しかし pnpm v11 の登場によって、この定番の構成には見直しの余地が生まれています。pnpm v11 以降では、pnpm/setup という別の action が使用できます。この action は pnpm の実行ファイルを直接取得し、Node.js のインストールも同じ step で担うため、actions/setup-node そのものが不要になります。

この記事では、実際にセットアップ step が 7 分かかっていたログを元に、pnpm/setup へ移行する手順を紹介します。

NOTE

2026 年 9 月時点の情報です。移行先として pnpm/setup v2.1.0、pnpm は v11.25.0 を対象にしています。pnpm/setup は pnpm v11 以降専用のため、v10 以前を使っているリポジトリはそのまま pnpm/action-setup を使い続けてください。

7 分かかっていた step

社内の Artifact Registry にライブラリを publish しているプロジェクトで、main へマージしたときに CI がなかなか終わらないことがありました。E2E テストが長いのだろうと思って見にいったところ、時間を使っていたのは changesets1 で publish するジョブです。さらに中を開くと、pnpm のセットアップ step が 7 分かかっていました。

Running self-installer...
 
added 1 package in 7m
 
1 package is looking for funding
  run `npm fund` for details
 
Checking for updates...
Switching pnpm from v11.19.0 to v11.25.0...
Successfully updated pnpm to v11.25.0
Installation Completed!

added 1 package in 7m の 1 行が 7 分です。pnpm setup というコマンドの実行が遅いのではなく、action が pnpm を用意し終えるまでに 7 分かかっていたことがわかります。

この step の末尾には、次の警告も出ていました。

[WARN] Detected a pnpm v10 installation layout at PNPM_HOME. The pnpm shims at PNPM_HOME have been refreshed so the new version is active, but pnpm v11 expects bins in PNPM_HOME/bin. Run "pnpm setup" to migrate your PATH to the v11 layout.

pnpm v10 を使っていないのにこの警告が出るという報告が action-setup の Issue #281 に上がっており、2026 年 9 月時点でも open のままです。警告自身も「shim は更新済みで新しいバージョンが有効になっている」と述べています。この警告を見て、workflow に pnpm setup の step を足す必要はありません。

pnpm v11 以降で使える pnpm/setup

pnpm のメジャーバージョンが 11 に上がったというニュースを見ていたため、バージョン周りが関係していそうだと当たりを付けて調べました。pnpm/action-setup の README には、冒頭に次の案内がありました。

This action has a successor: pnpm/setup.

For pnpm v11 and newer, use pnpm/setup instead. It downloads pnpm's self-contained release binary (no Node.js or npm required) and can install a JavaScript runtime (Node.js, Bun, or Deno) in the same step, replacing actions/setup-node.

pnpm v10 以前は pnpm/action-setup を使い、v11 以降は pnpm/setup を選べる、と読み解けます。
pnpm/setup は Node.js、Bun、Deno のいずれかを同じ step でインストールできる仕様のため、actions/setup-node の step は削除できます。

7 分の内訳を掘り下げるより、案内されている後継へ移るほうが早いと判断しました。

移行前の構成

移行前は次の 2 step です。

- name: Setup pnpm
  uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
 
- name: Setup Node.js
  uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
  with:
    node-version: "24"
    cache: "pnpm"

同じ形を使っているリポジトリは多いはずです。まずは自分の workflow で、セットアップ step の所要時間をログで確認してみましょう。

pnpm/setup へ置き換える

置き換えた結果が以下です。2 つあった step が 1 つになります。

- name: Setup pnpm and Node.js
  uses: pnpm/setup@703c52620218391530e48b9e8870d5c0082e1b9b # v2.1.0
  with:
    runtime: node@24
    cache: true

version を指定していない点に注意してください。action.yml のとおり、version を省略すると package.jsondevEngines.packageManager または packageManager からバージョンが読まれます。

{
  "packageManager": "pnpm@11.25.0"
}

どちらの宣言もない場合や、宣言が pnpm v10 以前を指している場合は、version: 11.25.0 のように明示します。pnpm/setup は pnpm v11 以降しか解決できないため、ここを省略したまま古いバージョンが宣言されていると失敗します。

cache の既定値は false です。pnpm/action-setup から移行するときは指定を忘れやすいため、ストアをキャッシュしたい場合は cache: true を明記してください。

install が二重に実行される場合

移行で見落としやすいのが pnpm install の扱いです。pnpm/setuppackage.json があるとき、既定で pnpm install まで実行します。install の既定値が true であるためです。

そのため、これまで別の step で install を書いていた場合、そのまま差し替えると install が 2 回実行されます。2 回目は依存関係に差分がないので、手元の検証では 26 ミリ秒で Already up to date と出て終わりました。CI の時間が延びるわけではありませんが、workflow を読んだ人が install の意図を追えなくなります。自前の step を残すなら、action 側の install を止めます。

  - name: Setup pnpm and Node.js
    uses: pnpm/setup@703c52620218391530e48b9e8870d5c0082e1b9b # v2.1.0
    with:
      runtime: node@24
      cache: true
+     install: false
 
  - run: pnpm install --frozen-lockfile

install を action に任せる場合、--frozen-lockfile を書く場所がなくなりますが、GitHub Actions では環境変数 CI が設定されるため、pnpm は既定で lockfile を更新せずに失敗します。実際に package.json の依存バージョンだけを書き換えて require-lockfile なしで実行したところ、次のエラーで止まりました。

[ERR_PNPM_OUTDATED_LOCKFILE] Cannot install with "frozen-lockfile" because pnpm-lock.yaml is not up to date with <ROOT>/package.json

既定で失敗しないのは、lockfile が 1 つも存在しない場合です。このとき pnpm はレジストリから解決して lockfile を新しく書き、正常終了します。lockfile の欠落を CI の失敗として扱いたい場合に require-lockfile: true を指定します。

- name: Setup pnpm and Node.js
  uses: pnpm/setup@703c52620218391530e48b9e8870d5c0082e1b9b # v2.1.0
  with:
    runtime: node@24
    cache: true
    require-lockfile: true

この指定があると、action は pnpm を実行する前に次のエラーで停止します。

`require-lockfile` is set but no pnpm-lock.yaml was found in . or above it.
Commit the lockfile, or unset `require-lockfile` to let pnpm resolve and write one.

ただし、install する step に環境変数を渡している場合は install: false を選んでください。action 側の install に環境変数を渡す入力がないためです。たとえば Playwright のブラウザダウンロードを抑止する PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD を install 時に渡している構成が該当します。

まとめ

  • pnpm v11 以降を GitHub Actions で使う場合、pnpm/setup へ移行するとセットアップの step が 1 つになる
  • pnpm/setup は Node.js を同じ step でインストールするため、actions/setup-node の step は削除できる
  • package.jsonpackageManager に pnpm v11 以降が宣言されていれば、version の指定を省略できる
  • pnpm/setup は既定で pnpm install まで実行するため、別 step で install しているなら install: false を指定する
  • install 時に環境変数を渡している構成では、action の install に環境変数を渡せないため自前の step を残す
  • GitHub Actions では lockfile が古いときの失敗は既定で起きる。require-lockfile: true が追加するのは lockfile の欠落を失敗として扱う条件
  • CI の実行時間を調べるときは、テストやビルドだけでなくセットアップ step の所要時間も確認する

参考

github.com のアイコン
github.com

GitHub - pnpm/setup: Install pnpm and a JavaScript runtime (Node.js, Bun, or Deno) in one GitHub actions step

Install pnpm and a JavaScript runtime (Node.js, Bun, or Deno) in one GitHub actions step - pnpm/setup

name: Setup pnpm with runtime
description: Install pnpm and a JavaScript runtime (Node.js, Bun, or Deno) in one step
branding:
  icon: package
  color: orange
inputs:
  version:
    description: |
      Version of pnpm to install: an exact version (`12.0.0`), a
      semver range (`^12.0.0`), or an npm dist-tag (`next-12`). Must resolve
      to pnpm v11 or newer — the action downloads pnpm's native per-platform
      executable directly, without needing Node.js or npm.
 
      When omitted, the version is read from `devEngines.packageManager` or
      `packageManager` in the project's package.json.
    required: false
  dest:
    description: Where to store pnpm files
    required: false
    default: ~/setup-pnpm
  runtime:
    description: |
      Runtime to install, in `<name>` or `<name>@<version>` form (matching
      pnpm's `packageManager` field syntax). Supported names: `node`, `bun`,
      `deno`. Examples: `node@22`, `node@lts`, `node@^24.4.0`, `bun@latest`,
      `deno@2`.
 
      When the version is omitted, the action falls back to the version
      declared in `devEngines.runtime` for the same name, or to `lts` (for
      `node`) / `latest` for others.
github.com のアイコン
github.com

GitHub - pnpm/action-setup: Install pnpm package manager

Install pnpm package manager. Contribute to pnpm/action-setup development by creating an account on GitHub.

github.com のアイコン
github.com

v6.0.9: false-positive "v10 installation layout" warning when self-updating from bootstrap 11.7.0 (still reproduces with pnpm 11.19.0) · Issue #281 · pnpm/action-setup

Summary pnpm/action-setup@v6.0.9 (0ebf471) still emits a false-positive v10 layout warning whenever it self-updates from the action's bootstrap pnpm (11.7.0) to the project's packageManager pin. Th...

Footnotes

  1. モノレポでパッケージのバージョン更新とリリースを管理するツール。変更内容をマークダウンで記録しておくと、バージョンの繰り上げと CHANGELOG の生成、レジストリへの publish までをまとめて実行できる。

関連記事