Skip to content

fix(ci): Dependency Unblock Check の probe 後の GitHub API 呼び出しを再試行する - #323

Open
kmryst wants to merge 1 commit into
mainfrom
322-unblock-check-fetch-retry
Open

kmryst wants to merge 1 commit into
mainfrom
322-unblock-check-fetch-retry

Conversation

@kmryst

@kmryst kmryst commented Oct 9, 2026

Copy link
Copy Markdown
Owner

目的(推奨)

Dependency Unblock Check の schedule 実行(2026-09-28 run 36388464626、2026-10-05 run 37275307924)が、
probe 後の GitHub API 呼び出しで MECHANISM: Unexpected evaluator error: fetch failed になっていた不具合を直す。
原因は Node.js 24.21.0(undici 7.29.1、nodejs/undici#5769)で、
probe の spawnSync 中にサーバー側で閉じられた keep-alive 接続を fetch が再利用すること(詳細は #322)。

変更内容(推奨)

  • scripts/ci/dependabot-unblock-check.mjs
    • createGitHubClient: GET に限り、cause が UND_ERR_SOCKET / EPIPE / ECONNRESET の fetch failed を 1 回だけ再試行する。POST と HTTP エラーは再試行しない
    • describeUnexpectedError を追加し、Unexpected evaluator error に error.cause の code / message を含める(例: fetch failed (cause: EPIPE write EPIPE))
  • scripts/ci/dependabot-unblock-check.test.mjs: 回帰テスト 6 本を追加(73 → 79 件)
  • docs/operations/dependency-unblock-check.md: 「赤(MECHANISM)の理由と対処」表に Unexpected evaluator error の行を追加し、再試行の仕様を追記

影響範囲(推奨)

  • 対象: Dependency Unblock Check の評価器(本リポジトリの schedule / workflow_dispatch と、workflow_call の呼び出し側)
  • 非対象: workflow 定義(.github/workflows/**)、job name / inputs / permissions、台帳と dependabot.yml、他の評価器(npm / yarn audit 系)

PRラベル(必須)

  • type: type:bug
  • area: area:ci-cd, area:docs
  • risk: risk:low
  • cost: cost:none
影響メモ(必要時のみ)

コスト根拠(小/中/大の場合): なし
リスク根拠(Medium/Highの場合): 該当なし(risk:low)。ただしマージ後の v1 タグ付け替えで呼び出し側に影響するため、厳密運用として扱う

可観測性/検証 条件付き

  • 合格条件: 単体テスト全件 pass、Node.js 24.21.0 の実 API で「GET → spawnSync 90 秒 → GET」が修正前は失敗し修正後は成功する
  • マージ後: 2026-10-12(月)01:15 UTC の schedule 実行が緑(OK: still blocked)であることを確認する
    • 本リポジトリの現 main は still blocked では probe 後に API を呼ばないため、この経路は schedule では踏まない
    • 再試行の経路は、下記の単体テスト(runFull に実クライアント + 偽 fetch を注入)と実 API での再現で確認している
  • 失敗時は Job Summary の Unexpected evaluator error: ... (cause: ...) で cause を確認できる

ロールバック 条件付き

  • 本 PR: revert PR を作成してマージする(評価器と docs のみの変更で、データや設定の移行はない)
  • 後続のタグ付け替え後に問題が出た場合: ADR-0008 の手順で v1 タグを v1.7.1(8c179a4)に戻す(force push のため実行前にユーザー確認)。v1.7.2 を参照させた呼び出し側は @v1.7.1 に戻す
テスト結果/検証手順

単体テスト(Node.js 24.18.0 / 24.20.0 / 24.21.0)

  • npm run test:dependency-unblock-check: 79 件 pass
  • npm run test:dependency-audit-policy: 191 件 pass
  • npm run test:workflow-input-contract: 9 件 pass
  • node --test scripts/ci/*.test.mjs: 279 件 pass
  • GITHUB_REPOSITORY=kmryst/idp-golden-path node scripts/ci/dependabot-unblock-check.mjs sync: exit 0
  • 追加したテストを修正前の評価器に対して実行すると、再試行・cause 表示・runFull 統合の 4 件が失敗する(POST / 対象外 cause を再試行しない 2 件は修正前後とも pass)

追加したテスト

  • 対象の cause(3 種)で GET が 1 回失敗しても、再試行で成功する
  • 2 回連続で失敗した GET はそれ以上再試行せず例外になる(呼び出し 2 回)
  • 対象外の cause(ENOTFOUND)と HTTP 502 は再試行しない
  • POST は再試行しない
  • 例外の説明に cause の code / message が含まれる
  • runFull(UNBLOCKED のフィクスチャ)に実クライアントと偽 fetch を注入し、probe 後最初の GET を EPIPE で失敗させても、再試行してコメントを投稿し exit 10 になる

実 API での再現(読み取りのみ。getIssue / listLabeledOpenIssues → spawnSync("sleep", ["90"]) → listIssueCommentBodies)

Node.js 評価器 結果 fetch 回数
24.21.0 修正前 fetch failed(EPIPE) 3
24.21.0 修正後 成功 4
24.20.0 修正前 成功 3
24.20.0 修正後 成功 3

CI について

  • Dependency Unblock Check は pull_request トリガーを持たない(セキュリティ契約、ADR-0013)ため、本 PR では評価器のテストは CI で走らない。上記のローカル実行で代替する
  • .github/workflows/** は変更していないため、required status checks との関係は変わらない

メモ(レビューポイント)

  • 再試行を GET に限定している点(POST はサーバー側で処理済みの可能性があり、コメントの重複投稿を避ける)
  • probe 後に setImmediate を待つ案と非同期 spawn 案は採らなかった(理由は fix(ci): Dependency Unblock Check の probe 後の GitHub API 呼び出しを再試行し fetch failed の cause を出す #322 の補足)
  • マージ後の後続作業(本 PR の範囲外、それぞれユーザー確認が必要)
    • ADR-0008 の「リリース手順(タグ運用)」に従い v1.7.2(patch)を作成し、v1 タグを付け替える(force push を伴う)
    • ticket-c2c-platform は @v1.7.1 に固定しているため、caller を @v1.7.2 に更新する(同リポジトリの Issue / PR、または Dependabot の更新 PR)
  • 定期チェックの連続失敗に気づく仕組みは本 PR の対象外(別途検討)

🤖 Generated with Claude Code

https://claude.ai/code/session_01PPszW4Rvm6ppEAvUWbRP6j

Closes #322

Node.js 24.21.0(undici 7.29.1)では、probe の spawnSync でイベントループが止まっている間に
サーバー側で閉じられた keep-alive 接続を fetch が再利用し、probe 後最初の GET が
fetch failed(cause: EPIPE / UND_ERR_SOCKET)になっていた。

- 接続の切断を示す cause(UND_ERR_SOCKET / EPIPE / ECONNRESET)の場合に限り、GET を 1 回だけ再試行する
- POST と HTTP エラーは再試行しない
- Unexpected evaluator error に error.cause の code / message を含める
- 回帰テストと運用 docs(MECHANISM の対処表、再試行の仕様)を追加する

Refs #322

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPszW4Rvm6ppEAvUWbRP6j
@kmryst kmryst added type:bug バグ修正 risk:low 低リスク・影響範囲小・ロールバック容易 cost:none コスト影響なし area:ci-cd CI/CD関連(GitHub Actions) area:docs ドキュメント関連 labels Oct 9, 2026

@amazon-q-developer amazon-q-developer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR adds comprehensive test coverage and documentation for the GitHub API retry mechanism that addresses connection failures during Dependency Unblock Check execution. The changes are well-structured and thoroughly tested.

The 6 new test cases properly verify:

  • Retry behavior for specific connection error codes (UND_ERR_SOCKET, EPIPE, ECONNRESET)
  • No retry after 2 consecutive failures
  • No retry for other error types or HTTP errors
  • POST requests are never retried (prevents duplicate comments)
  • Error description formatting includes cause details
  • Integration test with realistic scenario

The documentation clearly explains the retry mechanism, conditions, and limitations. All test assertions are appropriate and the code follows existing patterns.


You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:ci-cd CI/CD関連(GitHub Actions) area:docs ドキュメント関連 cost:none コスト影響なし risk:low 低リスク・影響範囲小・ロールバック容易 type:bug バグ修正

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(ci): Dependency Unblock Check の probe 後の GitHub API 呼び出しを再試行し fetch failed の cause を出す

1 participant