GitHub Actions:npm publish と「git@github.com: Permission denied (publickey)」
SSH にも npm のトークンにも問題はありません。npm は、渡されたパスを GitHub のリポジトリとして読みました。./・../・/・~/・file: のどれでも始まらない引数は、ファイルとして試す前に GitHub の略記として試されます(npm-package-arg の npa.js)。dist/pkg-1.0.0.tgz はこれに当てはまり、owner が dist、リポジトリが pkg-1.0.0.tgz になります。末尾の .tgz では変わりません。npm はそのリポジトリを SSH で git に聞き、ランナーには github.com 用の SSH の鍵がありません。レジストリには何も届いていません。
どう見えるか
npm error command git --no-replace-objects ls-remote ssh://git@github.com/release-tarballs/verax-ai-inventory-0.8.0.tgz.git npm error git@github.com: Permission denied (publickey).
ls-remote の行のリポジトリが、自分のパスに .git を足したものになっています。これが見分ける目印です。
直し方:パスを ./ で始める
- run: npm publish ./release-tarballs/verax-ai-inventory-0.8.0.tgz --provenance --access public
フォルダーも同じです。carlesandres/house は artifacts/npm-main ではなく ./artifacts/npm-main を公開しています(#351)。スラッシュが2つ以上あるパスは今はフォルダーとして読まれますが、npm のパッケージの指定の文書は、フォルダーはいつも / か ./ で始めるように書き、もう一方の読み方は古い振る舞いで、なくなるかもしれないとしています。そこにも ./ を付けてください。
グロブは、何にも当たらないと書いた文字のまま残ります。dsh-plugin-toolkit は、公開の前に tarball がちょうど1つあるかを確かめています(#10):
- name: Publish
run: |
set -- ./dist/*.tgz
if [ "$#" -ne 1 ] || [ ! -f "$1" ]; then
echo "expected one tarball in dist/, found: $*"
exit 1
fi
npm publish "$1" --provenance --access public
なぜリリースの日に出るか
この行は、たいてい初めて走ったときに失敗します:
- 公開を、前のジョブで固めた tarball からに変えた。ビルドのジョブが固めてアーティファクトにアップロードし、公開のジョブがそれを
dist/やrelease-tarballs/に取ってくるので、スラッシュが1つのパスになります。固めた tarball を公開する verax の変更は、0.8.0 のリリースまで一度も走っていませんでした(#252)。 - パスが短くなった。carlesandres/house はパッケージを
artifacts/npm-binary-*に移しました。それまでのパスはスラッシュが2つ以上でした(#351)。 - そのステップが一度も走っていなかった。qso の 1.4.0 は手で公開したのでジョブはそのステップを飛ばし、1.5.0 が初めての実行でした(#37)。
リリースの前に確かめる
--dry-run は引数を同じように読み、何も送りません。dsh-plugin-toolkit も verax もこれで失敗を再現し、verax では npm がこの指定を github:release-tarballs/… と呼んでいました:
npm publish dist/pkg-1.0.0.tgz --dry-run # 失敗:github:dist/pkg-1.0.0.tgz と読まれる npm publish ./dist/pkg-1.0.0.tgz --dry-run # tarball を読み、何も送らない
carlesandres/house と verax は、ワークフローの公開の行に ./ が無いと落ちる試験も足しました。
直したあと、そのまま再実行しない
再実行は、元の実行と同じ GITHUB_SHA と GITHUB_REF を使います(GitHub のドキュメント)。なのでタグで始まったリリースは、タグの時点のワークフロー、つまり古い行のまま走ります。上のプロジェクトは次のどちらかにしました:
- 新しいパッチの版とタグ。qso はライブラリのコードを変えずに 1.5.1 を出しました(#37)。
- その版が何も公開されていなければ、タグを直したコミットに付け直す。dsh-plugin-toolkit は 0.13.12 でそうしました(#10)。
もう一度公開する前に、npm に何が載っているかを見てください。npm view <name>@<version> version は、その版があれば版を出します。npm はある版の上には公開できません。いくつものパッケージを順に公開するジョブでは、失敗より前のパッケージは公開済みかもしれません。
見分け方
- 「ENEEDAUTH」や「404 Not Found - PUT」:npm はレジストリまで届き、有効なログインがありませんでした。
- 同じ
Permission denied (publickey)が git のステップや、git+ssh://の URL で書いた依存から出る:ランナーには本当に GitHub 用の SSH の鍵がありません。actions/checkoutはssh-keyの入力でデプロイキーを受け取ります。 - パスが入った「ENOENT」や「Could not read package.json」:npm はパスとして読み、そこには何もありませんでした。
失敗したジョブを IntelliJ IDEA から見るなら
Pipeline Inbox for GitHub Actions Workflows は、Lesstep が作っている JetBrains IDE(2024.1 以降)のプラグインです。すべてのリポジトリの実行を、ジョブ・ステップと一緒に IDE のツールウィンドウに並べ、いまのブランチの実行はステータスバーに出ます。読むのは無料、失敗したジョブの再実行・キャンセル・ワークフローの実行・デプロイのレビューは Pro(月 US$1.50・30日の無料試用つき)です。
GitHub・GitHub Actions は GitHub, Inc. の商標、npm は npm, Inc. の商標、IntelliJ IDEA は JetBrains s.r.o. の商標です。このページは GitHub, Inc.・npm, Inc.・JetBrains のいずれとも提携しておらず、承認も受けていません。
ほかに:npm publish と「ENEEDAUTH」 · 「Artifact download failed after 5 retries」 · 「Artifact not found for name」 · IntelliJ IDEA で使える GitHub Actions のプラグインの比較 · English