1157 字
6 分鐘

pnpm 11.21.0 修了 GitHub 依賴 CI 的 publickey 錯誤:升級前後怎麼驗證

如果 CI 執行 pnpm install 時出現 Permission denied (publickey),先確認依賴宣告是不是 github:owner/repoowner/repo 這類 GitHub shorthand。pnpm 11.21.0 在 2026 年 8 月 9 日發布,修正了非 SSH 宣告在某些探測失敗時被記成 SSH URL 的問題;這正是沒有 SSH key 的 CI runner 容易踩到的情況。

直接答案是:先把 CI 和本機都升到 pnpm 11.21.0 或更新版本,再檢查 pnpm-lock.yaml 是否仍記錄不必要的 SSH URL;但如果你明確寫的是 git+ssh,新版本不會替你改成 HTTPS,私有 repository 的認證也仍要另外設定。

先把錯誤和依賴寫法對上#

先在失敗的 runner 印出版本與依賴來源,不要只重試安裝:

Terminal window
pnpm --version
rg -n 'github:|git\+https|git\+ssh|git@github\.com' package.json pnpm-workspace.yaml pnpm-lock.yaml

這幾種寫法看起來都像「從 GitHub 安裝套件」,但它們對 transport 的意圖不同:

宣告transport 意圖CI 要注意什麼
github:acme/shared-libshorthand,沒有明確指定 SSHpnpm 11.21.0 會優先保留可攜的 HTTPS 解析結果
acme/shared-libGitHub shorthand同樣要看 registry/Git 探測後的 lockfile 結果
git+https://github.com/acme/shared-lib.git明確使用 HTTPS私有 repository 仍需要 HTTPS credential
git+ssh://[email protected]/acme/shared-lib.git明確使用 SSHrunner 必須有可用的 SSH key、agent 與 repository 權限

pnpm 11.21.0 的 release note 說明,對 shorthand 和非 SSH specifier,Git resolver 不再自行記錄 SSH URL;如果公開性探測失敗,會優先嘗試可攜的 HTTPS 路徑。這修的是解析選擇,不是替所有 GitHub 認證失敗提供通用繞過方式。

用 pnpm 11.21.0 重新產生可審查的 lockfile#

先在一個乾淨的工作副本測試,不要直接刪除 lockfile:

Terminal window
npm install --global [email protected]
pnpm --version
pnpm install --lockfile-only
git diff -- package.json pnpm-lock.yaml

如果只想驗證既有 lockfile 能否在 CI 重現,使用:

Terminal window
pnpm install --frozen-lockfile

兩個命令的目的不同。--lockfile-only 會讓你觀察新的 Git URL 是否被記錄;--frozen-lockfile 則拒絕在 CI 中偷偷改寫 lockfile。先看 diff,確認只有預期的 Git 解析變更,再把 lockfile 提交。

pnpm-workspace.yaml 仍是 pnpm v11 的一般設定位置;如果你同時在處理 v11 的 overridespatchedDependencies 遷移,可以參考 pnpm v11 設定從 package.json 搬到 workspace,不要把兩種不同問題混在同一個修復判斷裡。

CI 固定版本,而不是依賴 latest#

在 CI 內固定 pnpm 版本,至少讓安裝與本機使用相同 major、minor:

steps:
- name: Install pnpm
run: npm install --global [email protected]
- name: Check package manager version
run: pnpm --version
- name: Install dependencies
run: pnpm install --frozen-lockfile

這段範例只負責固定 package manager;actions/checkout、Node.js 版本和 cache 仍要依你的 workflow 另外設定。不要以「本機有 SSH key」推論 CI 也有同一把 key,反過來也不要為了讓 shorthand 通過就把長期 SSH 私鑰放進所有 runner。

私有 repository 仍然有認證邊界#

pnpm 11.21.0 對公開 GitHub shorthand 的解析改善,不代表私有 repository 可以無憑證下載。若 dependency 是 private repo,先決定團隊要用 HTTPS 還是明確的 SSH:

  • HTTPS:在 CI 的受信任 credential 流程中提供讀取權限,並避免把 token 直接寫進 package.json 或 lockfile。
  • SSH:明確使用 git+ssh,在 runner 建立短期、範圍受限的 deploy key 或其他經核准的 SSH 流程。
  • 本機與 CI:用同一種 transport 做測試,避免本機透過 SSH 成功、CI 卻被迫走另一條路。

若錯誤訊息仍是 GitHub 回傳的 Permission denied (publickey),先用 GitHub 官方的 SSH 排查流程確認 runner 是否真的需要 SSH;不要把 pnpm 版本修正誤當成權限授予。

升級完成的判斷標準#

這次變更完成的條件不是「安裝跑過一次」,而是三件事都能說明:pnpm 版本已固定、lockfile 的 Git URL 符合依賴宣告、CI 在不依賴開發者個人 SSH key 的前提下可重現安裝。若是 private repository,另外記錄 credential 的來源與失效方式,讓下一次輪替不必重新猜 transport。

常見問題#

Q: 升到 pnpm 11.21.0 後,明確寫 git+ssh 還會使用 SSH 嗎?#

A: 會。官方修正針對沒有明確要求 SSH 的 shorthand 與非 SSH specifier;git+ssh://[email protected]: 是使用者明確指定的 transport,仍需要 runner 上可用的 SSH 認證。

Q: pnpm install --frozen-lockfile 會自動修正舊的 SSH URL 嗎?#

A: 不會。--frozen-lockfile 的用途是拒絕改寫 lockfile。要處理 URL,先在乾淨環境用新版 pnpm 重新解析、檢查 diff,確認結果後提交 lockfile,再讓 CI 使用 frozen install。

Q: 公開 GitHub repository 也能使用 git+ssh 嗎?#

A: 可以,但 runner 仍要有 SSH key;公開 repository 不代表 SSH transport 不需要身份驗證。若不需要 SSH 的特殊設定,使用 GitHub shorthand 或 HTTPS 會更符合沒有私鑰的 CI runner。

參考資料:

pnpm GitHub Release:pnpm 11.21.0

pnpm:Settings (pnpm-workspace.yaml)

GitHub Docs:Error: Permission denied (publickey)

pnpm 11.21.0 修了 GitHub 依賴 CI 的 publickey 錯誤:升級前後怎麼驗證
https://laplusda.com/posts/pnpm-11-21-git-dependencies-ci/
作者
Zero
發佈於
2026-08-10
許可協議
CC BY-NC-SA 4.0
這篇文章有幫助嗎?

回報錯字、失效連結,或告訴我你想看的延伸主題。