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.

Publish an Allure report →

Related