Context
getLatestDeploymentStatus (src/review/visual/preview-url.ts:126-180) is the first step of the preview-URL discovery chain: it lists a head SHA/ref's GitHub Deployments (GET /deployments?sha=...&per_page=10, line 143) and, for each deployment id, lists that deployment's statuses (GET /deployments/{id}/statuses?per_page=10, line 158) — both single-page reads, never following GitHub's Link: rel="next" header.
This same file's own header comment (lines 78-84) explains exactly why that's unsafe for a GitHub list endpoint: "GitHub caps list endpoints at 100 items/page, so a single per_page=100 read silently truncates... this discovery would then return null/absent as if it genuinely didn't exist." The file's findAcrossPages helper (lines 99-115) exists specifically to walk Link: rel="next" for exactly this reason, and it is already used correctly by two sibling functions reading the same kind of GitHub list endpoint in this file: findPreviewUrlFromPrComments (line 263, /issues/{n}/comments) and getPreviewBuildState (line 299, /commits/{sha}/check-runs). getLatestDeploymentStatus is the one read path in this file that still does a bare single-page fetch.
This is a real, if narrower, gap than the deployments list itself: getLatestDeploymentStatus fetches per_page=10 for both the deployments list and each deployment's own status list. A head SHA/ref with more than 10 deployment records (repeated CI re-runs, multiple environments per push, a long-lived branch triggering many deploys against the same ref selector) can have the deployment carrying the real environment_url fall outside the fetched page, in which case this function under-reports (returns { url: null, failed: ... }) exactly as if no deployment existed — the same false-negative class the file's own header warns about, just on a third, still-unpaginated endpoint pair.
Prior art: fix(review): paginate preview-url.ts's PR-comment and check-run GitHub reads (#7469) already fixed this exact class of bug for the comment and check-run reads; a later gap-audit filed #7779 for findPreviewUrlFromChecks's own check-runs read, which #7469 also missed. getLatestDeploymentStatus's deployments/statuses reads are a third, still-open instance of the same gap — neither prior fix touched the Deployments API path.
Requirements
⚠️ Required pattern — reuse findAcrossPages (same file, preview-url.ts:99-115) exactly, the same way findPreviewUrlFromPrComments and getPreviewBuildState already do. Do not write a new pagination loop.
getLatestDeploymentStatus's deployments list fetch (${base}/deployments?${selector}&per_page=10) must paginate through all pages via findAcrossPages when searching for a usable deployment id, not just page 1.
getLatestDeploymentStatus's per-deployment statuses fetch (${base}/deployments/${id}/statuses?per_page=10) must similarly paginate via findAcrossPages when scanning for a success/in_progress status with an environment_url, not just page 1.
- The existing
sawFailure/sawPending bookkeeping and the function's overall return contract (DeploymentLookup) must be preserved exactly.
Deliverables
Test Coverage Requirements
src/review/** is under the top-level 99% patch coverage gate — the new pagination branches and both new tests must be covered.
Expected Outcome
getLatestDeploymentStatus finds a preview deployment's URL regardless of which page of deployments or deployment-statuses it lands on, consistent with the file's own findAcrossPages-based sibling functions and with the pagination fix already applied to the PR-comment and check-run reads.
Links & Resources
src/review/visual/preview-url.ts:126-180 (getLatestDeploymentStatus, the bug)
src/review/visual/preview-url.ts:99-115 (findAcrossPages, the pattern to reuse)
src/review/visual/preview-url.ts:253-281 and :289-314 (findPreviewUrlFromPrComments/getPreviewBuildState, the sibling functions already using it correctly)
src/review/visual/preview-url.ts:78-84 (the file's own header explaining why this class of bug matters)
- Prior fix:
fix(review): paginate preview-url.ts's PR-comment and check-run GitHub reads (#7469)
- Related open issue:
#7779 (findPreviewUrlFromChecks — a different, already-filed instance of the same gap in this file)
Context
getLatestDeploymentStatus(src/review/visual/preview-url.ts:126-180) is the first step of the preview-URL discovery chain: it lists a head SHA/ref's GitHub Deployments (GET /deployments?sha=...&per_page=10, line 143) and, for each deployment id, lists that deployment's statuses (GET /deployments/{id}/statuses?per_page=10, line 158) — both single-page reads, never following GitHub'sLink: rel="next"header.This same file's own header comment (lines 78-84) explains exactly why that's unsafe for a GitHub list endpoint: "GitHub caps list endpoints at 100 items/page, so a single
per_page=100read silently truncates... this discovery would then return null/absent as if it genuinely didn't exist." The file'sfindAcrossPageshelper (lines 99-115) exists specifically to walkLink: rel="next"for exactly this reason, and it is already used correctly by two sibling functions reading the same kind of GitHub list endpoint in this file:findPreviewUrlFromPrComments(line 263,/issues/{n}/comments) andgetPreviewBuildState(line 299,/commits/{sha}/check-runs).getLatestDeploymentStatusis the one read path in this file that still does a bare single-page fetch.This is a real, if narrower, gap than the deployments list itself:
getLatestDeploymentStatusfetchesper_page=10for both the deployments list and each deployment's own status list. A head SHA/ref with more than 10 deployment records (repeated CI re-runs, multiple environments per push, a long-lived branch triggering many deploys against the samerefselector) can have the deployment carrying the realenvironment_urlfall outside the fetched page, in which case this function under-reports (returns{ url: null, failed: ... }) exactly as if no deployment existed — the same false-negative class the file's own header warns about, just on a third, still-unpaginated endpoint pair.Prior art:
fix(review): paginate preview-url.ts's PR-comment and check-run GitHub reads (#7469)already fixed this exact class of bug for the comment and check-run reads; a later gap-audit filed#7779forfindPreviewUrlFromChecks's own check-runs read, which #7469 also missed.getLatestDeploymentStatus's deployments/statuses reads are a third, still-open instance of the same gap — neither prior fix touched the Deployments API path.Requirements
getLatestDeploymentStatus's deployments list fetch (${base}/deployments?${selector}&per_page=10) must paginate through all pages viafindAcrossPageswhen searching for a usable deployment id, not just page 1.getLatestDeploymentStatus's per-deployment statuses fetch (${base}/deployments/${id}/statuses?per_page=10) must similarly paginate viafindAcrossPageswhen scanning for asuccess/in_progressstatus with anenvironment_url, not just page 1.sawFailure/sawPendingbookkeeping and the function's overall return contract (DeploymentLookup) must be preserved exactly.Deliverables
getLatestDeploymentStatusinsrc/review/visual/preview-url.tspaginates both its deployments-list and per-deployment-statuses reads the same wayfindPreviewUrlFromPrComments/getPreviewBuildStatealready do in this file.environment_urlsits on page 2, asserting the preview URL is still found.success/in_progressstatus sits on page 2.Test Coverage Requirements
src/review/**is under the top-level 99% patch coverage gate — the new pagination branches and both new tests must be covered.Expected Outcome
getLatestDeploymentStatusfinds a preview deployment's URL regardless of which page of deployments or deployment-statuses it lands on, consistent with the file's ownfindAcrossPages-based sibling functions and with the pagination fix already applied to the PR-comment and check-run reads.Links & Resources
src/review/visual/preview-url.ts:126-180(getLatestDeploymentStatus, the bug)src/review/visual/preview-url.ts:99-115(findAcrossPages, the pattern to reuse)src/review/visual/preview-url.ts:253-281and:289-314(findPreviewUrlFromPrComments/getPreviewBuildState, the sibling functions already using it correctly)src/review/visual/preview-url.ts:78-84(the file's own header explaining why this class of bug matters)fix(review): paginate preview-url.ts's PR-comment and check-run GitHub reads (#7469)#7779(findPreviewUrlFromChecks— a different, already-filed instance of the same gap in this file)