Skip to content

Multiple reports per commit (parts)

When a commit's coverage comes from several jobs — a backend suite, a frontend suite, an e2e run — give each upload a part so gocov combines them instead of letting the last one win:

gocov upload -part backend  coverage.out
gocov upload -part frontend coverage/lcov.info
gocov upload -part e2e      e2e-lcov.info

The part name can also come from $GOCOV_PART, which is handy for matrix jobs that already expose the variant in the environment.

gocov keeps every upload but derives a merged report per commit from the latest upload of each part, and drives the status, gate, PR comment, Code Insights, badge and trend from that merged report. The repo page's file list is the merged report's too: it shows every part's files together (a Go backend's and a TypeScript frontend's side by side), and each file's source view shows the same merged coverage as its row. An upload's own page still shows only that upload's files; for a commit uploaded in more than one part it links to the same page with every part merged, which is where the PR comment, the build status and Code Insights link, so the figure they state is the one you land on. Re-uploading a part (a CI retry) replaces it rather than double-counting. When two parts report the same file, their line hit counts are summed, so a line covered by any part counts as covered.

An upload's page: the part it carried, and a note that the commit's report was merged from two parts

Part names are normalized (trimmed and lowercased) server-side, so Backend and backend are the same part. Uploads without a part use the reserved name default; passing -part default explicitly lands in that same bucket, so single-job setups are unchanged — a one-part merged report equals the upload.

Parts are merged as they arrive, in place. gocov does not wait for a fixed set of parts: while the jobs are still uploading, the merged report reflects only the parts received so far, so its total can read low and the gate can fail until the last part lands, then correct itself. Each upload step's log says which parts its figure covers (merged from 1 part so far: web), so an interim total is easy to tell apart — see CLI output. If a reviewer merges inside that window they may see an interim gate — sequence the gate check after all coverage jobs, or wait for the final status. A future expected_parts setting will let a repo hold status until every part is in; until then the self-healing behaviour above is the model.

A part that does not run at all is the other half of this: it is not carried forward from the previous commit, so the merged total drops until it lands. See Why coverage changed.