一年ぶりくらいにGitHub Actionsを使ってnpmパッケージを更新しようとしたら何かこけたので、通るようにした時にやったこと。
事象
なんかこんな感じのエラーが出てnpm publishに失敗した。
npm notice 1.6kB package.json
npm notice Tarball Details
npm notice name: @lycolia/ts-boilerplate-generator-cli
npm notice version: 0.28.1
npm notice filename: lycolia-ts-boilerplate-generator-cli-0.28.1.tgz
npm notice package size: 14.8 kB
npm notice unpacked size: 79.1 kB
npm notice shasum: 2ba5920ab2b46695bd996e86bf67b6a7cdb980cd
npm notice integrity: sha512-YHU4X10pXE7HP[...]RKmFhCpP4Gnmw==
npm notice total files: 25
npm notice
npm notice Publishing to https://registry.npmjs.org/ with tag latest and default access
npm notice Access token expired or revoked. Please try logging in again.
npm error code E404
npm error 404 Not Found - PUT https://registry.npmjs.org/@lycolia%2fts-boilerplate-generator-cli - Not found
npm error 404
npm error 404
npm error 404
npm error 404 Note that you can also install from a
npm error 404 tarball, folder, http url, or git url.
npm error A complete log of this run can be found in: /home/runner/.npm/_logs/2026-01-27T00_45_59_837Z-debug-0.log
Error: Process completed with exit code 1.
'@lycolia/ts-boilerplate-generator-cli@0.28.1' is not in this registry.
起きていたこと
- npmjsにあるAccess Tokensが全部消えてた
- Trusted publishing for npm packagesという話で、OIDC[1]を使ってGitHubと連携しないとGitHubなどのCI/CD、つまり自動化処理・バッチ処理から
npm publishできなくなっていた - これに対応するためにはnpm CLI version 11.5.1か、それ以降が必要
- またnpmjsのOIDC連携をするためには2FA認証が必須で、そのためにはパスキーが必要
- Access Tokenは最大90日までになり、無制限のものはなくなった
- Access Tokenで
npm publishを行う場合、2FAしていないとできない
- Access Tokenで
対応に必要なこと
- npmjsに2FA登録する。要パスキー
- npmjsからGitHubリポジトリへのOIDC連携
- GitHubリポジトリにある
npm publishしているyamlの修正 - npmのバージョンアップ
やったこと
- npmjsにパスキーを登録
- npmjsからGitHubリポジトリへのOIDC連携
- パッケージのSettingsタブを開き、Trusted publisherにリポジトリ情報を登録する
Enviroment nameは第三者向けの項目[2]なので、設定しなくていい

- Set up connectionボタンを押して連携する
- パッケージのSettingsタブを開き、Trusted publisherにリポジトリ情報を登録する
- GitHub Actionsのワークフローを直す
permissionsの部分を足し、npm publishのenvは不要なので削除name: npm publish on push to main on: push: branches: - main +permissions: + id-token: write + contents: read jobs: publish-to-npm: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version-file: '.nvmrc' cache: npm cache-dependency-path: package-lock.json registry-url: 'https://registry.npmjs.org' - name: npm continuous install run: npm ci - name: npm build run: npm run build - name: run publish run: npm publish - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH }}
.nvmrcのNode.jsのバージョンをv24.13.0にした- このバージョンにすると自動的にnpmのバージョンが適合したため
- この後、GitHub Actionsを使って
npm publishに成功すると、パッケージページやバージョン履歴ページには次のような表示が出るようになる


パスキー使いたくない問題
パスキーは端末依存で環境間共有の面倒さやGoogle縛りになるのが嫌などで入れたくない人も少なくないだろう。私もそう思う。正直パスキーありきのサービスは困る。
取り敢えず私の場合はEdgeを使っていて、Android Edgeへのパスキー共有はできないものの、いったんpublishするだけなら問題ないので、Edgeのパスキーを使うことにした。
どうしてもパスキーを使いたい、ほかの環境でも同期したいが、Googleに頼りたくない場合はKeePassXCというOSSを使うのが一つの手だ。
KeePassXCは暗号化されたデータベースファイルにIDとパスワードや、パスキーを記録するソフトウェアだ。複数環境への同期はNASなりSSHなり、クラウドストレージなどに鍵DBを保存して、それぞれの環境から読み書きすることで実現できる。
KeePassXCにはEdgeの拡張もあり、PCの中でKeePassXCを起動していればEdgeの拡張と同期してIDパスワードやパスキーを上手く管理してくれるようだった。ただ拡張機能が起動する前にKeePassXCが起動していないと手動で接続しないといけないなど、地味に面倒だった。
ただ調べた限りKeePassXCには公式のAndroidアプリがなく、サードパーティーアプリは毎回鍵ファイルを読みに行く実装のようで、オフライン時にも使うことのあるスマホでは運用に厳しさを感じた。逆に完全オフライン版もあるが、これはこれでAndroid側でDBを更新した時に別環境に飛ばすのが手間になるだろうからイマイチだ。
もう一つの選択肢としてはBitwardenを使う方法もある。こちらは公式がAndroidアプリを出しているほか、同期用のストレージを自前で用意する手間もかからない。
Bitwardenは、いわば1Passwordの無料版みたいな感じと言えるだろう。なお、BitwardenにはOSS版もあるので、セルフホスト運用もできるようだが、詳しくは調べていない。
私はBitwardenを軽く試してみたが、Edgeの自動入力機能に干渉しており、EdgeのパスワードDBを消し去らないとEdgeとBitwarden両方のパスワード入力補助が出てきて非常に邪魔だったことや、アニメーション設定をOFFにしても入力フィールドが飛び跳ねるアニメーションが出てきて嫌だったので、結局諦めた。せめて独立して動いてほしかった。
トラブルシューティング
Edgeで2FA認証しようとしたらパスキーがこけた
画像のような状態になった場合、何度かやり直すといけた。
「Two-factor authentication or granular access token with bypass 2fa enabled is required to publish packages.」と言われる
パスキーを使った2FAを登録することで解決した。
「npm error code EOTP」と言われる
npm notice Publishing to https://registry.npmjs.org/ with tag latest and default access
npm error code EOTP
npm error This operation requires a one-time password from your authenticator.
npm error You can provide a one-time password by passing --otp=<code> to the command you ran.
npm error If you already provided a one-time password then it is likely that you either typoed
npm error it, or it timed out. Please try again.
このようなエラーが出る場合、GitHub ActionsのWorkflowsのyamlファイルのルートに以下の記述が足りないので足す。
permissions:
id-token: write # Required for OIDC
contents: read
「npm error code ENEEDAUTH」と言われる
npm error code ENEEDAUTH
npm error need auth This command requires you to be logged in to https://registry.npmjs.org/
npm error need auth You need to authorize this machine using `npm adduser`
このようなエラーが出る場合、npmのバージョンが古いので11.5.1以上にすることで解決する。
あとがき
正直npmjsを利用するのはもうやめようかと思う。ぶっちゃけもうNode.jsと積極的に関わりたくないし、代替技術を探したいと感じた。少なくともプライベートではそう思う。
TypeScriptに限界を感じてきたでも書いたが、Node.jsのエコシステム周りには甚だうんざりしてきており、今回の件でより、さらに、もっと嫌になった。
取り敢えず静的解析とかそういうのは欲しいし、テストもしたい、ほんでLinuxフレンドリーで、Windowsでも動いてくれるとなおよい。簡単なツールを書くことが多いのもありコンパイル言語よりはインタプリタ言語のほうが好ましい。
そう考えるとやはり浮かんでくるのはPHPになってくるあたり、21年前に触れた私の初めてのプログラミング言語との出会いに戻ってくるあたりが面白い。PHPerはPHPerから逃れられない宿命でもあるのかもしれない。
今は肩書上フロントエンドエンジニアとかいうのを仕事にしているが、そこまで性に合っていない気もしてきているし、Web系のバックエンドではPHPの仕事もまだまだあるので、これを機にPHPに戻るのも一つありだとは思った。
関係ない話、何ならadiaryのせいでTypeScriptよりPerlの方が好感を持ててきているまであるので、私はたぶんどうかしているのだと思う。
PrettierというとTypeScriptやJavaScriptのコードを整形するツールであって、Markdownを整形するツールという意識のある人は少ないかもしれない。
それが実はPrettierはMarkdownの整形に使えるのだ。例えば次の図はPrettierを使ってMarkdownを整形しているシーンを撮ったものだ。具体的にはnpx prettier -w hoge.mdした時の前後を撮っている。
これは別の文書からコピペしたなどで書式が崩れることや単純なtypoでズレたりしたときに地味に効果を発揮してくれる。Prettier v2以前だと全角と半角文字の間の自動スペース挿入が嬉しかった人もいるだろうが、v3でこの機能は廃止されている。
他にもチーム開発だとMarkdownの細かい仕様に熟知した人は多くないので、最低限の書式を合わせるのにも役立つだろう。Markdownのインデント幅を変えたいが、コードフェンスの中のインデントは変えたくないみたいな用途みたいなカスタマイズもできるし、個人用途でも結構使える。
しかしフォーマッタの挙動がアップデートでころころ変わるのは割と不快なので、この辺りは何とかなってほしい気もする。
Node.jsのスクリプトを適当に書き次のようなWorkflowsを記述することで実行できる。勿論Dockerイメージを作ってそこから立ち上げることもできるので好みの問題。直に呼べる分、取り回しは楽だと思う
name: hoge
description: hoge
inputs:
GITHUB_TOKEN:
description: 'Workflowsを実行するリポジトリのGITHUB_TOKEN'
required: true
on:
workflow_call:
runs:
using: node20
main: dist/index.js
inputs:やoutputs:を記述すれば入出力の引数も定義できる。
inputs.GITHUB_TOKENについて
これを書いておくとoctokitを使ってGitHubのAPIを叩けるようになる。普通は何かAPIを叩くはずなので書いておいた方が良い。
以下は一例。
const github = require('@actions/github');
const core = require('@actions/core');
async function run() {
const token = core.getInput('GITHUB_TOKEN');
const octokit = github.getOctokit(token);
const { data: pullRequest } = await octokit.rest.pulls.get({
owner: 'octokit',
repo: 'rest.js',
pull_number: 123,
mediaType: {
format: 'diff'
}
});
console.log(pullRequest);
}
参考
- Metadata syntax for GitHub Actions (docs.github.com)
- @actions/github
投稿日:
prettier-vscodeをPrettier v3に対応させる試みは既にあるのだが、PRがRejectされている。レビューを見た感じtypoが原因っぽいのでtypoを直してみたのだがテストが落ちる。
まずテストが通らない原因だが、これはアサーション結果とテストコード、落ちた時の結果を三点比較したときに落ちた時の結果がプラグインを反映せずprettier -wされたものであることに気が付いた。次にこの解決法だが、原因が複数あるため、その切り分けが必要だと考えている。これはテスト走行時に指定されたプラグインが正しく読み込まれていればテストを通すことができるはずだが、package.jsonの指定通りインストールされているのかや、prettier側が正常に読み込めているのかなどが解らないと、真の原因が突き止められないためだ。
見た感じ割と面倒な仕組みなテストを実行してそうだったので一旦私は諦めることにした。これはprettier v3を個別にインストールすることで基本的に解決できるためだ。とはいえ、インストールできない条件だとその回避に苦労するのでネイティブに対応してほしい思いはあるが、検証するにも本家リポジトリにPRを向けないとテスト走行すらままならず、ローカルでの検証が極めて厳しいので、正直やる気が起きない。ぶっちゃけDockerで個別テストケースごとにビルドしてやるのが一番仕組みが単純で安全に思うが、敷くほど遅くなりそうだし、イメージのメンテも大変そうだし、アホほどイメージができるはずなので、容量も食いそうでなかなか微妙そうである。
そもそも論としてmainブランチを引っ張ってきてビルドすると、この時点で型エラーを吐くので、ここからどうにかしていく必要があり、割としんどい作業になりそうだ。
動機としてはcurlだと見えない部分があるので、自分でHTTPメッセージを手組みして送ってみたかった。
Node.jsとPHPのサーバーでリクエストが期待通り取得できたので、メッセージの実装としては問題ないと思われる。
検証用サーバー
以下のコードをNode.js v20.11.1を用いて検証
import http from 'node:http';
http
.createServer((req, res) => {
console.log(req.headers);
req.on('data', (chunk) => {
// body
console.log(Buffer.from(chunk).toString());
});
res.statusCode = 200;
res.end();
})
.listen(9999);
netcatコマンドによるリクエスト検証
GETリクエスト
echo -e 'GET / HTTP/1.1\r\nHost: localhost:9999\r\n\r\n' | nc localhost 9999
POSTリクエスト
echo -e 'POST / HTTP/1.1\r\nHost: localhost:9999\r\nContent-Length: 4\r\n\r\nhoge' | nc localhost 9999
備考
PHPで検証サーバーを作る場合
実際にAPサーバーでリクエストの中身をパース出来るかどうかの観点で見た場合にNode.jsよりPHPのが楽なので、PHPで作ってみた結果、軽くハマったので残しておく。
以下のコードを用いてPHP 8.0.29で検証サーバーを作る場合に、php -S 0.0.0.0:9999としてサーバーを起動すると、Content-Typeヘッダがない場合に正常な動作をしなかった。
<?php
var_dump($_SERVER);
var_dump($_REQUEST);
ncで検証サーバーを作る場合
デバッグ用。生のメッセージが見れるのでダンプしてdiffを取るなどでcurlとecho + ncの差分を見るのに使える。
nc -l 9999
HTTPメソッド名を非標準的なものにした場合の挙動
前述のNode.jsサーバーでは400 Bad Request、PHPサーバーでは501 Not Implementedが応答された。

