Context
src/review/visual/preview-url.ts's findPreviewUrlFromPrComments (line 210) and
getPreviewBuildState (line 242) both fetch exactly one page (per_page=100, no page parameter,
no check of the response's Link header) from /issues/{prNumber}/comments and
/commits/{sha}/check-runs respectively. On a PR with more than 100 discussion comments, or a
commit with more than 100 check-runs, either function can silently miss the resource it's looking
for (the Cloudflare Workers Builds bot's preview-URL comment, or its check-run) and return
null/"absent" as if it genuinely doesn't exist — no error is raised or logged, since a
successful-but-truncated page-1 response looks identical to a genuinely-empty one.
This repo already has an established, working pattern for exactly this class of bug:
githubPaginatedList (src/github/backfill.ts:2363-2379, per_page=100 + follow Link: rel="next"
until exhausted, bounded to PR_DETAIL_MAX_PAGES = 10 so a pathological PR can't turn one request
into an unbounded fetch loop) and the equivalent bespoke fix already applied for workflow-run
listing in src/github/app.ts:536-539 ("GitHub's default page size... means a repo whose head SHA
has more than one page of matching runs would silently leave page-2+ runs uncancelled... per_page=100
- follow Link: rel="next" until exhausted; bounded to MAX_WORKFLOW_RUN_LIST_PAGES").
Requirements
findPreviewUrlFromPrComments must follow the response's Link: rel="next" header and fetch
subsequent pages of /issues/{prNumber}/comments until either the bot's comment is found, the
Link header stops advertising a next page, or a bounded max-page count (mirror
PR_DETAIL_MAX_PAGES/MAX_WORKFLOW_RUN_LIST_PAGES's value of 10, or justify a different bound in
a comment) is reached — never an unbounded loop.
getPreviewBuildState must do the same for /commits/{sha}/check-runs.
- Both functions' existing fail-safe contract (return
null/"absent" on ANY read/parse failure,
never throw — see the file's own header comment: "Every helper degrades to null/absent on
failure — preview discovery must NEVER sink a review") must be preserved across every page,
including a mid-pagination failure (a later-page fetch failure should fall back to what was
already gathered from earlier pages, mirroring githubPaginatedList's own "a later-page failure
keeps the pages already fetched rather than dropping a successful first page" comment).
- Prefer reusing or extracting a shared pagination helper (either import/adapt the existing
githubPaginatedList-style Link-header walk, or add an equivalent local helper in
preview-url.ts if importing from src/github/backfill.ts isn't practical given this file's
standalone fetch helper) rather than inventing a third, different pagination shape in this repo.
Deliverables
Test Coverage Requirements
This repo's Codecov patch gate is 99%+ hard (branch-counted) on every changed line/branch in
src/**. All four new regression tests above must exercise the real functions against mocked
multi-page fetch responses (including realistic Link headers), not just assert on a hardcoded
single-page fixture.
Expected Outcome
A PR's preview URL and preview-build state are found reliably regardless of how many prior
discussion comments or CI check-runs exist on the PR/commit — matching the reliability this repo's
own githubPaginatedList/workflow-run-listing pagination already guarantees elsewhere.
Links & Resources
src/review/visual/preview-url.ts:210 (findPreviewUrlFromPrComments), :242
(getPreviewBuildState), :43 (githubJson, the shared fetch helper both functions use).
src/github/backfill.ts:2358-2379 (githubPaginatedList, the existing in-repo pagination
precedent to mirror). src/github/app.ts:536-539 (the analogous already-fixed workflow-run listing
bug, for reference on scoping/bounding the fix).
Context
src/review/visual/preview-url.ts'sfindPreviewUrlFromPrComments(line 210) andgetPreviewBuildState(line 242) both fetch exactly one page (per_page=100, nopageparameter,no check of the response's
Linkheader) from/issues/{prNumber}/commentsand/commits/{sha}/check-runsrespectively. On a PR with more than 100 discussion comments, or acommit with more than 100 check-runs, either function can silently miss the resource it's looking
for (the Cloudflare Workers Builds bot's preview-URL comment, or its check-run) and return
null/"absent"as if it genuinely doesn't exist — no error is raised or logged, since asuccessful-but-truncated page-1 response looks identical to a genuinely-empty one.
This repo already has an established, working pattern for exactly this class of bug:
githubPaginatedList(src/github/backfill.ts:2363-2379,per_page=100+ followLink: rel="next"until exhausted, bounded to
PR_DETAIL_MAX_PAGES = 10so a pathological PR can't turn one requestinto an unbounded fetch loop) and the equivalent bespoke fix already applied for workflow-run
listing in
src/github/app.ts:536-539("GitHub's default page size... means a repo whose head SHAhas more than one page of matching runs would silently leave page-2+ runs uncancelled... per_page=100
Requirements
findPreviewUrlFromPrCommentsmust follow the response'sLink: rel="next"header and fetchsubsequent pages of
/issues/{prNumber}/commentsuntil either the bot's comment is found, theLink header stops advertising a next page, or a bounded max-page count (mirror
PR_DETAIL_MAX_PAGES/MAX_WORKFLOW_RUN_LIST_PAGES's value of 10, or justify a different bound ina comment) is reached — never an unbounded loop.
getPreviewBuildStatemust do the same for/commits/{sha}/check-runs.null/"absent"on ANY read/parse failure,never throw — see the file's own header comment: "Every helper degrades to null/absent on
failure — preview discovery must NEVER sink a review") must be preserved across every page,
including a mid-pagination failure (a later-page fetch failure should fall back to what was
already gathered from earlier pages, mirroring
githubPaginatedList's own "a later-page failurekeeps the pages already fetched rather than dropping a successful first page" comment).
githubPaginatedList-style Link-header walk, or add an equivalent local helper inpreview-url.tsif importing fromsrc/github/backfill.tsisn't practical given this file'sstandalone fetch helper) rather than inventing a third, different pagination shape in this repo.
Deliverables
findPreviewUrlFromPrCommentspaginates through PR comments (bounded, Link-header-driven)instead of reading only page 1
getPreviewBuildStatepaginates through check-runs (bounded, Link-header-driven) instead ofreading only page 1
still found by
findPreviewUrlFromPrCommentsis still found by
getPreviewBuildStateagainst a pathological (always-
Link:rel="next") mock responseTest Coverage Requirements
This repo's Codecov patch gate is 99%+ hard (branch-counted) on every changed line/branch in
src/**. All four new regression tests above must exercise the real functions against mockedmulti-page
fetchresponses (including realisticLinkheaders), not just assert on a hardcodedsingle-page fixture.
Expected Outcome
A PR's preview URL and preview-build state are found reliably regardless of how many prior
discussion comments or CI check-runs exist on the PR/commit — matching the reliability this repo's
own
githubPaginatedList/workflow-run-listing pagination already guarantees elsewhere.Links & Resources
src/review/visual/preview-url.ts:210(findPreviewUrlFromPrComments),:242(
getPreviewBuildState),:43(githubJson, the shared fetch helper both functions use).src/github/backfill.ts:2358-2379(githubPaginatedList, the existing in-repo paginationprecedent to mirror).
src/github/app.ts:536-539(the analogous already-fixed workflow-run listingbug, for reference on scoping/bounding the fix).