Allure report has no history or trend
The Trend widget on the Overview page is empty, or shows a single dot. Open any test and the History tab is blank, and the Retries tab never lists the earlier attempt you know happened.
The report is fine. Allure simply never saw a previous run.
Where Allure 2 gets history from
Allure does not keep a database. Every generate is stateless, and the past arrives through one folder:
allure-results/
├── *-result.json ← this run
├── *-container.json
└── history/ ← the past — only if you put it here
├── history.json
├── history-trend.json
├── duration-trend.json
├── categories-trend.json
└── retry-trend.json
allure generate reads allure-results/history/, merges in the current
run, and writes the updated folder to allure-report/history/. The
loop only closes if you copy that output folder back into the next run's
results:
cp -r allure-report/history allure-results/history # before generating
allure generate allure-results --clean -o allure-report
Locally, this works by accident as long as the old report is still on
disk. In CI it never works by accident: every job starts on a clean
runner, allure-report/ does not exist, and every report is the first.
Carrying history between CI runs
Store history/ somewhere that outlives the job, restore it before
generating, save the new one after. On GitHub Actions the cache is the
least plumbing:
- name: Restore Allure history
uses: actions/cache@v4
with:
path: allure-history
key: allure-history-${{ github.ref_name }}-${{ github.run_id }}
restore-keys: allure-history-${{ github.ref_name }}-
- name: Generate report with history
if: always()
run: |
mkdir -p allure-results/history
cp -r allure-history/. allure-results/history/ 2>/dev/null || true
allure generate allure-results --clean -o allure-report
rm -rf allure-history && cp -r allure-report/history allure-history
The unique key plus a prefix restore-keys means every run restores the
newest history and saves its own. Two caveats: GitHub evicts caches not
read for 7 days, and caches are scoped to a branch (plus the default
branch), so a feature branch starts from main's trend.
The same shape works with a build artifact or with the gh-pages branch
that hosts the report — what matters is restore, generate, save, in
that order. if: always() matters too: the run you most want in the
trend is the one where tests failed, and a failing test step skips
everything after it by default.
Tests that never get history
If the trend fills in but some tests still show no history, the problem
is identity, not storage. Allure matches a test across runs by its
historyId, computed from the full name and the parameters.
Any parameter that changes per run gives the test a new identity every time:
- a timestamp or generated id in a parametrized test
- a temp directory path passed in as a parameter
- a test name that includes the build number
Exclude the volatile parameter from the identity instead of dropping it from the report. In allure-pytest:
allure.dynamic.parameter("workdir", str(tmp_path), excluded=True)
Allure Java has the same switch on Allure.parameter(...). Renaming a
test or moving it to another class also resets its history — expected,
but it surprises people after a refactor.
Label the trend: executor.json
A trend without build labels is a row of anonymous dots. Write
allure-results/executor.json before generating:
{
"name": "GitHub Actions",
"type": "github",
"buildOrder": 482,
"buildName": "CI #482",
"buildUrl": "https://github.com/acme/app/actions/runs/123",
"reportUrl": "https://commareports.com/p/YOUR_REPORT_ID"
}
buildOrder becomes the x-axis and reportUrl makes each trend point
clickable back to that run's report — which only helps if that URL still
works next month.
Allure 3
Allure 3 drops the folder. History lives in one file set by
historyPath in the allurerc config, and each generate appends to it.
The CI pattern is the same — restore the file, generate, save it — with
one file instead of five.
The other half of history: the reports themselves
The trend tells you a test went red on build 482. To find out why you need build 482's report, and in most pipelines that report was a build artifact that expired under retention weeks ago.
Publish the generated allure-report/ directory to the same report on
every run and each build becomes a revision: one stable link, with
earlier runs still openable from the revision history. The data/ and
widgets/ JSON upload alongside index.html, so the report loads over
HTTPS instead of going blank from file://.
Reviewers can then comment on the failing test itself rather than
pasting the stack trace into chat (comment on HTML).
Limits: entry HTML 5 MB; assets 25 MB per file, 250 MB and 500 files
per report. Large Allure runs have one JSON per test case — watch the
file count, or use --single-file.
Try it
Comma is free — unlimited reports, unlimited commenters, unlimited revision history.