The artifact link in the PR is a 404
Someone opens a six-month-old incident review, clicks the link to the failing test report, and gets a 404. Or a code review resumes after a long weekend and the coverage artifact is gone. The link was never permanent; it just hadn't expired yet when it was pasted.
What actually deleted it
Retention is only one of four mechanisms, and it is often not the one that got you.
| Mechanism | Where | What it does |
|---|---|---|
| Time-based retention | GitHub 90d, GitLab 30d, CircleCI 30d | Deletes by age, regardless of whether anyone is reading it |
| Keep-latest-successful | GitLab | Deletes superseded pipelines' artifacts immediately, at any age |
| Build discarders | Jenkins, TeamCity | Deletes by build count — ten green builds erase build #1 |
| Visibility change | Any provider | Repo goes private, and every anonymous link stops resolving |
The count-based ones are the surprise. A busy repository can retire an artifact within a day.
Can you get it back?
From the provider, no. Retention deletion is permanent — there is no undelete on any major CI provider, and support cannot restore it.
The only recovery is re-running the job, which is a real option and often a mirage:
- The commit still exists, but the runner image has moved on.
npm installresolves different transitive versions than it did then.- The scanner's vulnerability database has been updated, so the report you regenerate is not the report you lost.
- The external service the test hit has changed its responses.
For anything you might need to cite later — a compliance scan, an incident timeline, a benchmark you claimed a regression against — a regenerated report is a different document. It is evidence with a new date on it.
Making the next one permanent
Separate the two things CI artifacts are being asked to do:
Machine artifacts — caches, build outputs, files a downstream job downloads. Keep uploading these. Retention is correct for them, and shorter is better.
Documents — test reports, coverage, scans, benchmarks, anything a person is meant to read. Publish these to an address you own:
# once, by hand: create the report, save the id as a CI variable
# every run thereafter:
curl -sS -X PATCH "https://commareports.com/api/v1/reports/$COMMA_REPORT_ID" \
-H "Authorization: Bearer $COMMA_API_TOKEN" \
-H "Content-Type: application/json" \
--data @<(jq -Rs '{html: .}' htmlcov/index.html)
One id, one URL, for the life of the project. Each run appends a revision rather than overwriting, so the history is browsable and any two builds can be diffed — which is the thing artifact retention was destroying. Setup per provider is in publish from CI.
Why this changes review, not just storage
A permanent link is also a place to put the conversation. Reviewers comment on the failing assertion inside the report instead of quoting it into a chat thread that scrolls away (comment on HTML), and the thread stays attached across revisions — so "we decided this flake was environmental" is still readable next to the test six months later.
Try it
Comma is free — unlimited reports, unlimited commenters, unlimited revision history. Nothing expires.
Create a permanent report URL →