Test, build, and share data
Preserve failure evidence
Upload test reports, screenshots, logs, and summaries even when the main test step fails.
When tests fail, the default behavior stops the job. Steps after the failing step never run. If your screenshot upload comes after npm test, you get a red run and no picture of what broke.
That sends people rerunning jobs blindly. Reruns cost minutes and sometimes hide intermittent failures.
Upload steps should use explicit conditions. if: failure() uploads only on failure. if: always() also runs on cancel unless you add extra guards.
Upload evidence even on failure
Use if: always() on upload steps that must run when tests fail:
- name: Run browser tests
run: npm run test:e2e
- name: Upload Playwright report
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: playwright-report/
retention-days: 7
always() runs unless the job was cancelled. You get HTML reports and screenshots from the failed run.
Be careful: always() also runs on success. That is fine for test reports. It is not fine for deploy steps.
Keep evidence focused and redacted
Do not dump every environment variable into a public artifact. Secrets can leak through build logs, .env copies, or HAR files.
Collect what a developer needs:
- junit or HTML test report
- one failing screenshot
- trimmed server log
Set retention-days so old failures do not fill storage forever.
Diagnose without a local rerun
Force a browser test to fail on purpose. Open the workflow run page, download the artifact, and find the failing selector from the report alone.
If a teammate can do that without you on a call, your evidence step works.
Large video artifacts slow downloads. Prefer one PNG and a short HTML report for pull request debugging.
Try this on your own project: break one assertion, confirm the artifact still uploads, then fix the test.
Lesson completed