@aramassa/ai-rules 0.5.3 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,611 @@
1
+ ---
2
+ type: development
3
+ category: cd
4
+ focus: github-actions, npm-publish, troubleshooting
5
+ language:
6
+ - typescript
7
+ - nodejs
8
+ framework: npm
9
+ applyTo: ".github/workflows/**/*.yml"
10
+ ---
11
+
12
+ # GitHub Actions npm Package Publishing Troubleshooting Guide
13
+
14
+ ## 概要
15
+
16
+ GitHub Actions でnpmパッケージ公開時に発生する一般的なエラーとその解決方法をまとめたガイドです。
17
+ CI/CD環境特有の問題、npm workspaces構成での依存関係管理、Dual Registry公開、バージョン管理など、実際のトラブルシューティング履歴に基づいた知見を提供します。
18
+
19
+ ## 問題1: vitest コマンドが見つからない (ENOENT: vitest: not found)
20
+
21
+ ### 発生したエラー
22
+
23
+ ```bash
24
+ sh: 1: vitest: not found
25
+ npm error Lifecycle script `test` failed with error:
26
+ npm error code 127
27
+ npm error path /home/runner/work/mcp-docs-collector/packages/cli-utils
28
+ npm error command failed
29
+ ```
30
+
31
+ ### 原因
32
+
33
+ npm workspaces 構成において、各パッケージ(`packages/cli-utils`, `packages/common`)の `package.json` で `test` スクリプトが `vitest` コマンドを使用していたが、`vitest` が各パッケージの `devDependencies` に含まれていなかった。
34
+
35
+ **なぜローカルでは動いていたのか:**
36
+ - ルートの `package.json` に `vitest` が `devDependencies` として存在
37
+ - ローカル環境では npm workspaces のホイスティング機能により、子パッケージからもルートの `node_modules` にある `vitest` にアクセス可能
38
+ - CI環境では、依存関係の解決が異なり、各パッケージが独立して実行されるため、明示的に `devDependencies` に含める必要がある
39
+
40
+ ### 解決方法
41
+
42
+ 各パッケージに必要な `devDependencies` を追加:
43
+
44
+ ```bash
45
+ # packages/cli-utils に追加
46
+ npm install --save-dev vitest typescript @types/node --workspace=packages/cli-utils
47
+
48
+ # packages/common に追加
49
+ npm install --save-dev vitest typescript @types/node --workspace=packages/common
50
+
51
+ # クリーンインストール
52
+ rm -rf node_modules package-lock.json
53
+ npm install
54
+ ```
55
+
56
+ **結果の package.json:**
57
+
58
+ ```json
59
+ {
60
+ "devDependencies": {
61
+ "@types/node": "^22.16.5",
62
+ "typescript": "^5.8.3",
63
+ "vitest": "^3.2.4"
64
+ }
65
+ }
66
+ ```
67
+
68
+ ### 予防策・チェックリスト
69
+
70
+ #### 開発時の確認事項
71
+
72
+ - [ ] **新規パッケージ作成時**: 使用する全てのコマンド(テストランナー、ビルドツール等)を `devDependencies` に明示的に追加
73
+ - [ ] **スクリプト追加時**: そのスクリプトが依存する全てのパッケージが `dependencies` または `devDependencies` に含まれているか確認
74
+ - [ ] **ローカルテスト**: 以下のコマンドで各パッケージが独立して動作するか確認
75
+
76
+ ```bash
77
+ # 各パッケージのディレクトリで実行
78
+ cd packages/cli-utils
79
+ rm -rf node_modules
80
+ npm install
81
+ npm test
82
+ npm run build
83
+ ```
84
+
85
+ #### CI/CD 設定時の確認事項
86
+
87
+ - [ ] **依存関係の明示**: ワークスペース構成では、各パッケージが独立して実行可能な状態にする
88
+ - [ ] **統一性の確認**: 同じツールを使うパッケージ間で、バージョンを統一する
89
+ - [ ] **Docker環境でのテスト**: ローカル環境と異なる動作を検証
90
+
91
+ ```bash
92
+ # Docker環境でのテスト例
93
+ docker run --rm -v $(pwd):/app -w /app node:20 npm install
94
+ docker run --rm -v $(pwd):/app -w /app node:20 npm test
95
+ ```
96
+
97
+ #### 設計原則
98
+
99
+ **原則1: 明示的依存管理**
100
+ - ホイスティングに依存せず、各パッケージが必要とする依存を明示的に宣言
101
+ - 「動いているから良い」ではなく、「設計として正しい」状態を目指す
102
+
103
+ **原則2: 独立性の担保**
104
+ - 各パッケージは単独で `npm install && npm test && npm build` が実行できる状態にする
105
+ - ルートパッケージの依存に依存しない
106
+
107
+ ---
108
+
109
+ ## 問題2: npm version コマンドの出力形式エラー (Invalid format 'v0.0.2')
110
+
111
+ ### 発生したエラー
112
+
113
+ ```bash
114
+ Error: Unable to process file command 'output' successfully.
115
+ Error: Invalid format 'v0.0.2'
116
+ ```
117
+
118
+ ### 原因
119
+
120
+ GitHub Actionsの `version-bump` ジョブで、`npm version` コマンドの出力を直接 `$GITHUB_OUTPUT` に書き込んでいたが、以下の問題があった:
121
+
122
+ 1. **出力形式の不確実性**: `npm version` は `v0.0.2` という形式(vプレフィックス付き)で出力するが、処理によっては期待される形式と異なる
123
+ 2. **Git統合の複雑さ**: `npm version` の `-m` オプションと Git の自動タグ作成が干渉
124
+ 3. **非推奨アクションの使用**: `actions/create-release@v1` が deprecated
125
+
126
+ ### 解決方法
127
+
128
+ **変更前:**
129
+ ```yaml
130
+ - name: Bump version and create tag
131
+ id: bump
132
+ working-directory: packages/cli-utils
133
+ run: |
134
+ NEW_VERSION=$(npm version ${{ github.event.inputs.version_bump }} -m "chore(cli-utils): release v%s")
135
+ echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
136
+ git push origin HEAD --tags
137
+
138
+ - name: Create GitHub Release
139
+ uses: actions/create-release@v1
140
+ ```
141
+
142
+ **変更後:**
143
+ ```yaml
144
+ - name: Bump version and create tag
145
+ id: bump
146
+ working-directory: packages/cli-utils
147
+ run: |
148
+ # Bump version without creating git tag
149
+ npm version ${{ github.event.inputs.version_bump }} --no-git-tag-version
150
+
151
+ # Get the new version from package.json
152
+ NEW_VERSION=$(node -p "require('./package.json').version")
153
+ echo "new_version=v${NEW_VERSION}" >> "$GITHUB_OUTPUT"
154
+
155
+ # Commit and tag
156
+ git add package.json
157
+ git commit -m "chore(cli-utils): release v${NEW_VERSION}"
158
+ git tag "cli-utils-v${NEW_VERSION}"
159
+ git push origin HEAD --tags
160
+
161
+ - name: Create GitHub Release
162
+ uses: softprops/action-gh-release@v1
163
+ ```
164
+
165
+ ### 予防策・チェックリスト
166
+
167
+ #### バージョン管理のベストプラクティス
168
+
169
+ **原則1: Git操作の分離**
170
+ - `--no-git-tag-version` フラグで npm の Git 統合を無効化
171
+ - commit と tag を明示的に作成することで、制御を明確にする
172
+
173
+ **原則2: 確実なバージョン取得**
174
+ ```bash
175
+ # ✅ 推奨: package.json から直接読み取る
176
+ VERSION=$(node -p "require('./package.json').version")
177
+
178
+ # ❌ 非推奨: npm version の出力に依存
179
+ VERSION=$(npm version patch) # 出力形式が不確実
180
+ ```
181
+
182
+ **原則3: $GITHUB_OUTPUT の安全な使用**
183
+ ```bash
184
+ # ✅ 推奨: 引用符で囲む
185
+ echo "key=value" >> "$GITHUB_OUTPUT"
186
+
187
+ # ❌ 非推奨: 引用符なし(スペースや特殊文字で問題発生)
188
+ echo "key=value" >> $GITHUB_OUTPUT
189
+ ```
190
+
191
+ #### GitHub Actions のベストプラクティス
192
+
193
+ - [ ] **最新アクションの使用**: deprecated なアクションは使わない
194
+ - `actions/create-release@v1` → `softprops/action-gh-release@v1`
195
+ - [ ] **タグの命名規則**: モノレポでは `<package-name>-v<version>` 形式を使用
196
+ - [ ] **冪等性の確保**: 同じ操作を複数回実行しても安全な設計にする
197
+
198
+ ---
199
+
200
+ ## 問題3: Dual Registry での認証エラー (ENEEDAUTH)
201
+
202
+ ### 発生したエラー
203
+
204
+ ```bash
205
+ npm error code ENEEDAUTH
206
+ npm error need auth This command requires you to be logged in to https://npm.pkg.github.com
207
+ npm error need auth You need to authorize this machine using `npm adduser`
208
+ ```
209
+
210
+ ### 原因
211
+
212
+ **根本原因**: `package.json` の `publishConfig.registry` に GitHub Packages のレジストリが設定されていたため、npmjs.org への publish もそのレジストリに向かってしまった。
213
+
214
+ **詳細**:
215
+ ```json
216
+ {
217
+ "publishConfig": {
218
+ "access": "public",
219
+ "registry": "https://npm.pkg.github.com" // ← これが原因
220
+ }
221
+ }
222
+ ```
223
+
224
+ - `actions/setup-node@v4` で `registry-url: https://registry.npmjs.org/` を設定しても、`package.json` の `publishConfig.registry` が優先される
225
+ - GitHub Packages 用の認証情報で npmjs.org にアクセスしようとして失敗
226
+
227
+ ### 解決方法
228
+
229
+ npmjs.org への publish 前に、`publishConfig.registry` を削除するステップを追加:
230
+
231
+ ```yaml
232
+ - name: Update publishConfig for npmjs.org
233
+ working-directory: packages/cli-utils
234
+ run: |
235
+ # Remove GitHub Packages registry from publishConfig
236
+ node -e "
237
+ const fs = require('fs');
238
+ const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
239
+ if (pkg.publishConfig) {
240
+ delete pkg.publishConfig.registry;
241
+ }
242
+ fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
243
+ "
244
+ echo "Updated package.json publishConfig for npmjs.org"
245
+
246
+ - name: Publish to npmjs.org
247
+ run: npm publish --access public --verbose
248
+ working-directory: packages/cli-utils
249
+ env:
250
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
251
+ ```
252
+
253
+ ### 予防策・チェックリスト
254
+
255
+ #### Dual Registry 設計のベストプラクティス
256
+
257
+ **アプローチ1: publishConfig を動的に変更(今回の方法)**
258
+
259
+ 利点:
260
+ - 1つの `package.json` で管理
261
+ - Git履歴に変更が残らない
262
+
263
+ 欠点:
264
+ - ワークフローが複雑になる
265
+ - 開発者がローカルで publish する際に注意が必要
266
+
267
+ **アプローチ2: 別々の package.json を管理**
268
+
269
+ ```bash
270
+ # package.json (開発用、GitHub Packages向け)
271
+ {
272
+ "publishConfig": {
273
+ "registry": "https://npm.pkg.github.com"
274
+ }
275
+ }
276
+
277
+ # package.npmjs.json (npmjs.org向け)
278
+ {
279
+ "publishConfig": {
280
+ "registry": "https://registry.npmjs.org"
281
+ }
282
+ }
283
+ ```
284
+
285
+ **アプローチ3: publishConfig.registry を使わない(最もシンプル)**
286
+
287
+ ```json
288
+ {
289
+ "publishConfig": {
290
+ "access": "public"
291
+ // registry は指定しない
292
+ }
293
+ }
294
+ ```
295
+
296
+ ワークフローで明示的にレジストリを指定:
297
+ ```bash
298
+ # GitHub Packages
299
+ npm publish --registry=https://npm.pkg.github.com
300
+
301
+ # npmjs.org
302
+ npm publish --registry=https://registry.npmjs.org
303
+ ```
304
+
305
+ #### チェックリスト
306
+
307
+ - [ ] **レジストリの優先順位を理解**
308
+ 1. `package.json` の `publishConfig.registry`
309
+ 2. `.npmrc` ファイル
310
+ 3. `actions/setup-node@v4` の `registry-url`
311
+ 4. コマンドライン引数 `--registry`
312
+
313
+ - [ ] **認証情報の分離**
314
+ - GitHub Packages: `NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}`
315
+ - npmjs.org: `NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}`
316
+
317
+ - [ ] **Dry-run での検証**
318
+ ```bash
319
+ # publish 前に必ず実行
320
+ npm publish --dry-run
321
+ ```
322
+
323
+ - [ ] **ローカルテストの注意点**
324
+ - ローカルの `.npmrc` が CI と異なる動作を引き起こす可能性
325
+ - テスト用のプライベートレジストリを使用して検証
326
+
327
+ ---
328
+
329
+ ## 問題4: Provenance 機能のリポジトリ可視性エラー
330
+
331
+ ### 発生したエラー
332
+
333
+ ```bash
334
+ npm error code E422
335
+ npm error 422 Unprocessable Entity - PUT https://registry.npmjs.org/@aramassa%2fmcp-docs-collector-cli-utils
336
+ Error verifying sigstore provenance bundle: Unsupported GitHub Actions source repository visibility: "private".
337
+ Only public source repositories are supported when publishing with provenance.
338
+ ```
339
+
340
+ ### 原因
341
+
342
+ `npm publish --provenance` オプションは**パブリックリポジトリでのみサポート**されている機能。
343
+
344
+ **Provenance(来歴証明)とは:**
345
+ - npm v9.5.0+ で導入された機能
346
+ - パッケージがどこで、どのように、誰によってビルドされたかを証明
347
+ - Sigstore を使用した署名により、supply chain attack を防止
348
+ - **パブリックリポジトリのみ対応**(プライベートリポジトリでは使用不可)
349
+
350
+ ### 解決方法
351
+
352
+ `--provenance` フラグを削除:
353
+
354
+ **変更前:**
355
+ ```yaml
356
+ - name: Publish to npmjs.org
357
+ run: npm publish --provenance --access public --verbose
358
+ ```
359
+
360
+ **変更後:**
361
+ ```yaml
362
+ - name: Publish to npmjs.org
363
+ run: npm publish --access public --verbose
364
+ ```
365
+
366
+ ### 予防策・チェックリスト
367
+
368
+ #### Provenance 使用の判断基準
369
+
370
+ **✅ Provenance を使うべき場合:**
371
+ - パブリックリポジトリである
372
+ - 広く公開されるパッケージである
373
+ - Supply chain security が重要である
374
+ - npm v9.5.0+ を使用している
375
+
376
+ **❌ Provenance を使えない/使うべきでない場合:**
377
+ - プライベートリポジトリである
378
+ - 社内専用パッケージである
379
+ - npm のバージョンが古い
380
+
381
+ #### 条件分岐の実装例
382
+
383
+ リポジトリの可視性に応じて provenance を切り替える場合:
384
+
385
+ ```yaml
386
+ - name: Check repository visibility
387
+ id: repo-visibility
388
+ run: |
389
+ VISIBILITY=$(gh repo view --json visibility -q .visibility)
390
+ echo "visibility=$VISIBILITY" >> "$GITHUB_OUTPUT"
391
+ env:
392
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
393
+
394
+ - name: Publish to npmjs.org (Public)
395
+ if: steps.repo-visibility.outputs.visibility == 'public'
396
+ run: npm publish --provenance --access public --verbose
397
+
398
+ - name: Publish to npmjs.org (Private)
399
+ if: steps.repo-visibility.outputs.visibility != 'public'
400
+ run: npm publish --access public --verbose
401
+ ```
402
+
403
+ #### チェックリスト
404
+
405
+ - [ ] **リポジトリの可視性を確認**
406
+ - GitHub リポジトリの Settings > General > Danger Zone
407
+ - `gh repo view --json visibility`
408
+
409
+ - [ ] **npm バージョンの確認**
410
+ ```bash
411
+ npm --version # 9.5.0 以上必要
412
+ ```
413
+
414
+ - [ ] **Provenance の検証**
415
+ ```bash
416
+ # パッケージ公開後に検証
417
+ npm view <package-name> --json | jq .dist.attestations
418
+ ```
419
+
420
+ ---
421
+
422
+ ## 全体的なベストプラクティス
423
+
424
+ ### 1. CI/CD パイプラインの設計原則
425
+
426
+ #### 原則1: 明示的かつ予測可能
427
+ - 暗黙的な依存や動作に頼らない
428
+ - すべての設定を明示的に記述
429
+ - 環境変数、シークレット、設定ファイルを明確に文書化
430
+
431
+ #### 原則2: 段階的な検証
432
+ ```yaml
433
+ # 推奨: 各段階で検証
434
+ - name: Install dependencies
435
+ run: npm install
436
+
437
+ - name: Verify installation
438
+ run: npm list || true
439
+
440
+ - name: Run tests
441
+ run: npm test
442
+
443
+ - name: Verify build
444
+ run: npm run build
445
+
446
+ - name: Verify package contents
447
+ run: npm pack --dry-run
448
+ ```
449
+
450
+ #### 原則3: 冪等性の確保
451
+ - 同じ入力で何度実行しても同じ結果
452
+ - 失敗時の状態が予測可能
453
+ - ロールバックが容易
454
+
455
+ ### 2. エラーハンドリングのベストプラクティス
456
+
457
+ #### デバッグ情報の充実
458
+ ```yaml
459
+ - name: Debug environment
460
+ if: failure()
461
+ run: |
462
+ echo "=== Environment Variables ==="
463
+ env | grep -E '^(NODE|NPM|CI)' || true
464
+ echo "=== npm config ==="
465
+ npm config list
466
+ echo "=== .npmrc ==="
467
+ cat ~/.npmrc || echo "No .npmrc found"
468
+ echo "=== package.json ==="
469
+ cat package.json
470
+ ```
471
+
472
+ #### ログの詳細化
473
+ ```yaml
474
+ # --verbose フラグを積極的に使用
475
+ npm install --verbose
476
+ npm test --verbose
477
+ npm publish --verbose
478
+ ```
479
+
480
+ ### 3. モノレポ(Workspaces)での注意点
481
+
482
+ #### 依存関係の管理
483
+ ```json
484
+ // ルート package.json
485
+ {
486
+ "workspaces": ["packages/*"],
487
+ "devDependencies": {
488
+ // 共通のビルドツール
489
+ "typescript": "^5.8.3",
490
+ "eslint": "^8.57.1"
491
+ }
492
+ }
493
+
494
+ // 各パッケージ package.json
495
+ {
496
+ "devDependencies": {
497
+ // そのパッケージ固有のツール
498
+ "vitest": "^3.2.4",
499
+ "@types/node": "^22.16.5"
500
+ }
501
+ }
502
+ ```
503
+
504
+ #### 独立性のテスト
505
+ ```bash
506
+ # 各パッケージが独立して動作するか確認
507
+ for pkg in packages/*; do
508
+ echo "Testing $pkg"
509
+ (cd "$pkg" && rm -rf node_modules && npm install && npm test)
510
+ done
511
+ ```
512
+
513
+ ### 4. セキュリティのベストプラクティス
514
+
515
+ #### シークレット管理
516
+ - [ ] `GITHUB_TOKEN`: 自動で提供される(リポジトリアクセス用)
517
+ - [ ] `NPM_TOKEN`: npmjs.org への publish 用(手動設定)
518
+ - [ ] `GH_TOKEN`: より広い権限が必要な場合(手動設定)
519
+
520
+ #### 最小権限の原則
521
+ ```yaml
522
+ permissions:
523
+ contents: write # タグ作成に必要
524
+ id-token: write # provenance に必要
525
+ # その他の権限は付与しない
526
+ ```
527
+
528
+ ---
529
+
530
+ ## トラブルシューティングフローチャート
531
+
532
+ ```mermaid
533
+ graph TD
534
+ A[CI/CD エラー発生] --> B{エラーの種類は?}
535
+
536
+ B -->|コマンドが見つからない| C[依存関係の問題]
537
+ C --> C1[package.json の devDependencies を確認]
538
+ C1 --> C2[ローカルで npm install && npm test]
539
+ C2 --> C3[Docker環境でテスト]
540
+
541
+ B -->|認証エラー| D[レジストリ/認証の問題]
542
+ D --> D1[publishConfig.registry を確認]
543
+ D1 --> D2[.npmrc の設定を確認]
544
+ D2 --> D3[NODE_AUTH_TOKEN を確認]
545
+
546
+ B -->|形式エラー| E[出力形式の問題]
547
+ E --> E1[GITHUB_OUTPUT の形式を確認]
548
+ E1 --> E2[引用符の有無を確認]
549
+ E2 --> E3[値の取得方法を見直す]
550
+
551
+ B -->|422エラー| F[Provenance/可視性の問題]
552
+ F --> F1[リポジトリがパブリックか確認]
553
+ F1 --> F2{パブリック?}
554
+ F2 -->|Yes| F3[npm version を確認]
555
+ F2 -->|No| F4[--provenance を削除]
556
+ ```
557
+
558
+ ---
559
+
560
+ ## チェックリスト: 新規パッケージ公開時
561
+
562
+ ### 事前準備
563
+ - [ ] リポジトリの可視性を確認(public/private)
564
+ - [ ] 必要なシークレットを設定(NPM_TOKEN等)
565
+ - [ ] パッケージ名の重複を確認 `npm search <package-name>`
566
+
567
+ ### package.json の確認
568
+ - [ ] `name`: スコープ付きの場合 `@scope/package-name`
569
+ - [ ] `version`: セマンティックバージョニング準拠
570
+ - [ ] `main`, `types`: 正しいエントリポイント
571
+ - [ ] `files`: 公開するファイルを明示
572
+ - [ ] `publishConfig`: レジストリ設定を確認
573
+ - [ ] `dependencies`: 実行時に必要なもののみ
574
+ - [ ] `devDependencies`: ビルド/テストツールを含む
575
+
576
+ ### ワークフローの確認
577
+ - [ ] Node.js バージョンの指定
578
+ - [ ] レジストリの明示的な設定
579
+ - [ ] 認証トークンの正しい使用
580
+ - [ ] dry-run での検証ステップ
581
+ - [ ] エラー時のデバッグ情報出力
582
+
583
+ ### テスト
584
+ - [ ] ローカルでの `npm pack --dry-run`
585
+ - [ ] Docker環境でのテスト
586
+ - [ ] テストレジストリでの公開テスト(verdaccio等)
587
+
588
+ ### 公開後
589
+ - [ ] npmjs.org でパッケージを確認
590
+ - [ ] `npm install <package-name>` で動作確認
591
+ - [ ] README、ドキュメントの表示確認
592
+
593
+ ---
594
+
595
+ ## まとめ
596
+
597
+ 今回の一連のエラー対応を通じて学んだ重要なポイント:
598
+
599
+ 1. **明示的な依存管理**: ホイスティングに頼らず、必要な依存を明示する
600
+ 2. **Git操作の分離**: ツールの自動化に頼らず、明示的に制御する
601
+ 3. **レジストリ設定の優先順位**: package.json > .npmrc > 環境設定
602
+ 4. **機能の制約を理解**: provenance はパブリックリポジトリのみ
603
+ 5. **段階的な検証**: 各ステップで動作を確認し、問題を早期発見
604
+
605
+ これらの知見を活かし、今後は初回からスムーズに CI/CD パイプラインを構築できるようにする。
606
+
607
+ ## 関連ドキュメント
608
+
609
+ - [npm Package Publishing Workflow 実装ルール](./npm-publish.md) - 標準的なワークフロー実装
610
+ - [GitHub Actions Testing Policy](../test/github-actions-no-tests.md) - ワークフローテストの方針
611
+ - [GitHub Issue Template Rules](./github.md) - Issue作成時のテンプレート使用方法