fix: surface comment-post failures instead of swallowing them#6
Conversation
upsertComment now returns boolean (true = wrote, false = intentionally skipped) across the PrPlatform interface and both impls, and lets real read/write failures throw instead of warn-and-continue. run-ci tracks the true outcome (posted/postError), warns loudly on a failed post, and folds the post error into the fail-on-drift message. AzDO findExistingComment paginates every thread page via x-ms-continuationtoken (capped at MAX_THREAD_PAGES) so a busy PR can't hide our comment and trigger a duplicate post; a read failure throws rather than masquerading as 'not found'. Both the read (pagination) and write paths now share a single fetchWithTimeout helper so the new pagination path inherits the same 15s abort hardening as other calls. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe ChangesupsertComment boolean contract + AzDO pagination + runCi error tracking
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/platforms/github.ts (1)
86-95: 🧹 Nitpick | 🔵 Trivial | 💤 Low valueGitHub comment lookup lacks pagination, risking duplicates on busy PRs.
findExistingCommentfetches only the first 100 comments. If a PR accumulates more than 100 issue comments (rare but possible on long-running PRs), the existing Polder Drift comment could be missed, causing a duplicate post on subsequent runs.The AzDO implementation now paginates; consider adding pagination here for parity, or document the limitation as acceptable.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platforms/github.ts` around lines 86 - 95, The findExistingComment method only retrieves the first 100 comments due to the per_page limit and lacks pagination logic. To fix this, implement pagination by fetching comments in a loop, making multiple calls to this.octokit.rest.issues.listComments with incrementing page numbers until the response returns fewer than 100 comments. Accumulate all comments from all pages into a single array before filtering for the marker. This ensures no existing Polder Drift comments are missed on PRs with more than 100 comments, preventing duplicate posts on subsequent runs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/platforms/github.ts`:
- Around line 86-95: The findExistingComment method only retrieves the first 100
comments due to the per_page limit and lacks pagination logic. To fix this,
implement pagination by fetching comments in a loop, making multiple calls to
this.octokit.rest.issues.listComments with incrementing page numbers until the
response returns fewer than 100 comments. Accumulate all comments from all pages
into a single array before filtering for the marker. This ensures no existing
Polder Drift comments are missed on PRs with more than 100 comments, preventing
duplicate posts on subsequent runs.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: d4481e81-132e-49db-85b6-c2fe89feade5
⛔ Files ignored due to path filters (2)
dist/cli/index.jsis excluded by!**/dist/**,!dist/**dist/index.jsis excluded by!**/dist/**,!dist/**
📒 Files selected for processing (5)
src/platforms/azdo.tssrc/platforms/github.tssrc/platforms/types.tssrc/run-ci.tstests/platforms.test.ts
…#7) findExistingComment fetched only the first 100 issue comments, so on a PR with >100 comments the existing Polder Drift comment could be missed and a duplicate posted on the next run. Walk every page of listComments (per_page: 100, incrementing page) until a short page, capped at MAX_COMMENT_PAGES so a misbehaving API can't loop forever. Octokit throws on a non-2xx response, so a transient list error propagates rather than masquerading as "no existing comment" — matching the AzDO findExistingComment behavior fixed in #6. Adds GitHub pagination tests mirroring the AzDO fetch-stub tests, and rebuilds dist/ since the action runs from the bundle. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Problem
upsertCommentreturnedvoidand swallowed read/write failures into awarn(). A failed post (e.g. the AzDO build identity lacking Contribute to pull requests, a 403, a transient list error) was indistinguishable from a successful one —run-cireportedposted: trueregardless, and a fail-on-drift run could go red with no comment on the PR explaining why. On Azure DevOps a single-page threads read could also miss our existing comment on a busy PR and post a duplicate.Change
upsertCommentnow returnsbooleanacross thePrPlatforminterface and both impls:true= a comment was actually created/updated,false= the write was intentionally skipped (nothing to do, or no credentials). Real read/write failures throw instead of warn-and-continue.run-citracks the true outcome (posted/postError), warns loudly when a post fails ("it is NOT on the PR"), and folds the post error into the fail-on-drift failure message so a red build explains itself.findExistingCommentpaginates every thread page viax-ms-continuationtoken(capped atMAX_THREAD_PAGES = 50so a misbehaving server can't loop forever). A read failure throws rather than masquerading as "not found", which would duplicate-post on the next run.fetchWithTimeouthelper, so the new pagination path inherits the same 15sAbortControllerabort as every other call — no duplicated boilerplate.Tests
tests/platforms.test.tscovers: pagination following the continuation token to a later page, theMAX_THREAD_PAGESloop guard, throw-on-read-failure (no duplicate POST), token-empty skip reported asfalse, andrun-cipost-state tracking including a failed write folded into the fail-on-drift message (against a real git base, since fail-on-drift is gated on base availability). Full suite: 198 passing, typecheck clean,distrebuilt.🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Tests