Use Codecov coverage flags to split CI uploads by test suite
Upload separate coverage reports for unit, integration, and end-to-end tests under one commit using Codecov flags and codecov.yml.
21 Jun 2026, 00:10 UTC

Problem. A CI pipeline that runs unit, integration, and end-to-end tests often uploads one coverage report for everything. The resulting percentage hides which test suite exercised which lines, so a drop in coverage cannot be assigned to a specific suite.
Useful takeaway. Use Codecov coverage flags. Attach a flag name to each upload with the uploader's -F option, define the flags in codecov.yml, and Codecov reports coverage per flag. You can then gate pull requests on individual flags instead of one aggregate number.
How a Codecov flag works
A coverage flag is a label attached to an upload. Codecov attributes the lines in the uploaded report to that flag. The codecov.yml flags map defines each flag name and options such as carryforward. When carryforward is true, Codecov preserves the flag's last reported coverage if a later upload omits that flag. Without carryforward, omitting a flag can clear that flag's previously reported status on Codecov.
Worked configuration and CI commands
This example splits uploads into three flags. The exact codecov.yml schema should be checked against current Codecov documentation before rollout.
flags:
unit:
carryforward: true
integration:
carryforward: true
e2e:
carryforward: false
Run each upload in the CI job that produces the corresponding report, after the test suite finishes. Required permission: a Codecov upload token with repository upload scope, provided to CI as a secret such as CODECOV_TOKEN.
# Unit test job
codecov -F unit -f coverage/unit.xml
# Integration test job
codecov -F integration -f coverage/integration.xml
# End-to-end test job
codecov -F e2e -f coverage/e2e.xml
Expected checks: the uploader exits with code 0, the Codecov commit status appears for the commit, and the repository dashboard Flags breakdown lists each flag key. Relevant risks: a missing -f file fails the upload, overlapping path coverage across flags can double-count lines, and omitting a flag without carryforward can clear its prior status.
| Flag | Report file | carryforward | Effect when job skipped |
|---|---|---|---|
| unit | coverage/unit.xml | true | Last unit coverage preserved |
| integration | coverage/integration.xml | true | Last integration coverage preserved |
| e2e | coverage/e2e.xml | false | No current e2e status for this commit |
Carryforward in split pipelines
If the integration job is skipped in a particular commit, carryforward: true keeps the last successful integration coverage visible on Codecov. If carryforward is false or unset, Codecov may show no current integration status for that commit, which can fail a pull-request gate that expects integration coverage.
Limits and common mistakes
- Flags do not automatically merge coverage across parallel CI jobs. Each
-Fupload is attributed to that flag; carryforward preserves the previous value, it does not combine two reports uploaded under the same flag in one commit. - Keep flag path sets disjoint. Overlapping coverage globs can cause the same line to be counted under multiple flags or attributed unexpectedly.
- Defining a flag in
codecov.ymldoes not by itself create a pull-request status check. Per-flag gating must be configured separately in Codecov for each flag name. - Treat
CODECOV_TOKENas a secret. Do not hardcode it in configuration files.
Check the result
- Run
codecov --helpin the CI image to confirm the installed uploader supports-Fand-f. - After a pipeline run, open the Codecov repository dashboard and check the Flags breakdown for each flag key you defined.
- Compare the commit status UI against the CI upload logs; confirm the uploader exit code was 0 and that each expected flag appears.
Rollback
Uploading coverage changes Codecov state. To stop flagged uploads, remove -F from CI steps and remove the flag definitions from codecov.yml, then resume aggregate uploads without flags. Historical flag data remains governed by Codecov retention; removing the configuration stops new flagged uploads but does not delete prior flag reports.
Verification required before rollout
This research is based on general Codecov behavior and has not been verified against your Codecov account or the current uploader version. Confirm the flags schema, carryforward semantics, and per-flag status-check configuration in Codecov documentation before enabling pull-request gating.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.