Skip to content

fix: paginate list endpoints so history and comments are found - #319

Open
AlveElde wants to merge 4 commits into
ctrf-io:mainfrom
AlveElde:fix/paginate-run-artifacts
Open

fix: paginate list endpoints so history and comments are found#319
AlveElde wants to merge 4 commits into
ctrf-io:mainfrom
AlveElde:fix/paginate-run-artifacts

Conversation

@AlveElde

@AlveElde AlveElde commented Aug 3, 2026

Copy link
Copy Markdown

Fix #314

  1. Paginate run artifacts. Walk every page with per_page: 100, and pass the artifact name to the endpoint's name filter so the common case stays a single request. The name check in processArtifactsFromRun remains as a fallback for deployments that ignore the filter.
  2. Skip expired artifacts, isolate per-artifact failures. GitHub keeps listing artifacts after retention passes and answers 410 on download. Now that history reaches runs old enough to be expired, that exception escaped the loop and discarded every report already collected for the run, so the whole run was dropped.
  3. Paginate pull request comments. findExistingMarkedComment could not find the reporter's own comment on a busy pull request, so the action posted a new comment on every run instead of updating, and isLatest compared against the wrong comment.
  4. Report only the latest attempt of a re-run. All attempts share a run id, so a re-run left two same-name artifacts. Both were counted, consuming two slots of previous-results-max and double-counting the run in the flaky and fail rate insights.

Side note

sourcemap: true in tsup.config.ts is worth revisiting separately. The committed dist/index.js.map is 16 MB, and across 103 rebuilt versions its blobs account for 31 MiB of the repository's 55 MiB pack, so roughly 300 KB of permanent history per dist-touching commit. Nothing consumes it: the action runs node dist/index.js with no --enable-source-maps anywhere in action.yml or the workflows.

fetchArtifacts listed a run's artifacts with a single request, so it
only ever saw the 30 newest. In a repo with many artifacts per run the
CTRF report often falls outside that window, the run then looks like it
has no report, and every history-backed report falls back to showing a
single run.

Page through the full list with per_page 100, and pass the artifact
name to the endpoint's name filter so the common case stays one
request. An empty name is ignored, since name= would match nothing.
The name check in processArtifactsFromRun stays as a fallback for
deployments that ignore the filter.
GitHub keeps listing artifacts after their retention has passed, and
downloading one answers 410. Since history now reaches runs far enough
back to be expired, that exception escaped processArtifactsFromRun and
discarded every report already collected for the run, so metrics.ts
dropped the whole run.

Skip artifacts marked expired, and handle download and unzip failures
per artifact so an unreadable one costs only itself.
listComments made a single request, so it returned only the oldest 30
comments. findExistingMarkedComment then failed to find the reporter's
own comment on any pull request with more discussion than that, and
handleComment posted a new comment on every run instead of updating the
existing one. The isLatest check compared against the wrong comment for
the same reason.
All attempts of a workflow run share a run id, so a re-run left two
same-name artifacts on the run. Both were downloaded and pushed, which
made metrics.ts count one run as two entries of previous-results-max and
double-counted its results in the flaky and fail rate insights. The old
30 artifact window usually hid the extra one.

Take the highest artifact id, which is the latest upload, and fall back
to an earlier attempt only when the newer one cannot be read.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: previous run history is empty when a run has more than 30 artifacts

1 participant