Publishing Reports to Perforce
Check PerfGuard's HTML reports into version control after a run so QA and the rest of the team can open them straight from their workspace — with the depot history acting as an audit trail. The same feature targets Perforce, Git, or a custom command; this tutorial covers Perforce, with a short section on Git and custom commands at the end.
In This Tutorial
How Publishing Works
After a report is produced — by perfguard report, or automatically at the end of perfguard run / perfguard run-scenario — PerfGuard runs two Perforce commands in your workspace:
p4 [-p PORT] [-u USER] [-c CLIENT] reconcile <report files> p4 [-p PORT] [-u USER] [-c CLIENT] submit -d "<message>" <report files>
reconcile opens new or changed report files for add/edit; submit checks them in. The commands run with no shell, so report paths are passed as plain arguments — spaces and special characters are safe.
p4 not installed, nothing new to submit, or the files are outside the client view — PerfGuard prints a Warning: and the command still returns its normal exit code. A failed publish never aborts a capture or a comparison. A publish.log recording each command and its output is written into the report directory.
p4 changes -m1 ...#have) and shows it as CL<n> on the report's Revision line, in history.json, and in the comparison JSON. Set it explicitly with --revision, or via the PERFGUARD_REVISION / P4_CHANGELIST environment variables.
Prerequisites
Before you publish to Perforce, make sure you have:
- The Helix command-line client (
p4) on PATH. Verify withp4 -V. - A Perforce connection. Set
P4PORTandP4USERin your environment (the standard Perforce setup), or put them in the suitepublishblock (see Step 6). - A client workspace whose view maps the directory your reports are written to. By default that is
<project>/Saved/PerfGuard/Results. Either setP4CLIENTin your environment /.p4config, or pass--p4-client. - An authenticated ticket if your server requires it. Run
p4 loginfirst.
If you haven't set up PerfGuard itself yet, start with the Quick Start tutorial and the Reading Performance Reports tutorial — publishing picks up where report generation leaves off.
Quick Start: Publish a Report
Re-generate a report from a results directory and submit it in one command:
perfguard report <results_dir> --commit p4 --commit-message "PerfGuard nightly reports"
With P4PORT and P4USER set in the environment and a workspace that maps <results_dir>, this reconciles and submits the report files. Confirm the change landed:
p4 changes -m1 p4 describe -s <change#>
reconcile sees as new — so you get a new changelist per run instead of "nothing to submit".
Workspace and Connection
p4_port and p4_user are read from the environment when you don't pass them. The workspace is taken from P4CLIENT / .p4config unless you pass --p4-client to name it explicitly:
perfguard report <results_dir> --commit p4 \ --p4-client qa-reports-ws --commit-message "PerfGuard reports"
This is useful on a shared CI agent where the environment's default client isn't the one mapped to your reports directory.
Choosing Exactly What to Submit
By default PerfGuard reconciles the whole results directory you point it at. That includes every timestamped report and the publish.log it writes. To submit only specific files, pass --commit-paths:
perfguard report <results_dir> --commit p4 --commit-message "DemoScene report" \ --commit-paths <results_dir>/report_20260618_120000.html <results_dir>/index.html
Only the listed files are reconciled and submitted. Use this when your reports directory also holds files you don't want in the depot.
Publishing Automatically After a Run
Add a publish block to your suite.json. perfguard run submits after the suite finishes and the report is generated:
{
"scenarios": [
{ "name": "DemoScene" }
],
"publish": {
"backend": "p4",
"message": "PerfGuard CI reports",
"p4_client": "ci-reports-ws"
}
}
perfguard run suite.json --commit p4
Keys in the publish block: backend (p4), message, paths (optional list, same as --commit-paths), p4_client, p4_port, p4_user. CLI flags override the block, so a shared suite can set the workspace while CI passes the message per build. p4_port and p4_user still fall back to the environment when omitted from both.
CI Usage
In a CI job, capture and publish in one step so QA can sync the workspace and open the HTML report without leaving Perforce:
perfguard run-scenario DemoScene \ --project ./Game.uproject --ue-root "$UE_ROOT" \ --commit p4 --p4-client "$P4CLIENT" \ --commit-message "PerfGuard report — $CI_PIPELINE_ID"
The CI agent needs P4PORT / P4USER / P4CLIENT set and an authenticated ticket (p4 login or P4PASSWD). Because publishing is non-fatal, a Perforce hiccup won't fail the build — check the job log for a Warning: and the report directory's publish.log if a submit is missing.
Troubleshooting
If a submit doesn't appear, the publish.log in the report directory records each command and its output. The most common causes:
| Symptom | Cause & fix |
|---|---|
Connect to server failed; check $P4PORT |
P4PORT is unset or the server is unreachable. Confirm with p4 info. |
file(s) not in client view |
The report directory isn't mapped in your workspace view. Add it to the client spec, or point --commit-paths at a mapped path. |
| Nothing is submitted | reconcile found no new or changed files since the last submit. Reports are timestamped, so a fresh run normally produces new files. |
publish command not found: p4 |
The Helix client isn't on PATH. Install it and re-run. |
| Submit succeeds locally but QA can't see it | Confirm everyone maps the same depot path in their client view. |
Git and Custom Commands
The same feature publishes to Git or runs a custom command. With Git, PerfGuard adds, commits, and optionally pushes the report files:
# Add, commit, and (optionally) push the report files perfguard report <results_dir> --commit git \ --commit-message "PerfGuard reports" \ --git-push --git-remote origin --git-branch main
A custom command lets you hand the report off to any uploader. {dir}, {files}, and {message} are substituted as separate arguments (no shell), so paths with spaces stay intact:
perfguard report <results_dir> --commit command \ --commit-command "reporttool upload {dir} --label {message}"
Both honor the same publish block ("backend": "git" or "command") and the same non-fatal, best-effort behavior as Perforce. See the CI/CD Pipeline Setup tutorial for how publishing fits into a full pipeline.