Skip to content
Latchkey

Adding Codecov to GitHub Actions

Generate a coverage report in CI and ship it to Codecov so every PR shows a coverage diff.

Codecov ingests a coverage report from your test step and renders a coverage diff on each pull request. The flow is: run tests with coverage, produce a report file, then hand it to the official codecov-action. This guide shows the minimal wiring plus the token and gotchas that trip people up.

What you need

  • A CODECOV_TOKEN repository secret (required for private repos; recommended for public ones to avoid rate limits).
  • A test step that emits a coverage file (lcov.info, coverage.xml, or coverage/coverage-final.json).
  • The codecov/codecov-action workflow action.

The workflow

Run your tests with coverage, then upload. The action auto-detects common report paths, but you can pin one with files:.

.github/workflows/ci.yml
- name: Test with coverage
  run: npm test -- --coverage

- name: Upload to Codecov
  uses: codecov/codecov-action@v4
  with:
    token: ${{ secrets.CODECOV_TOKEN }}
    files: ./coverage/lcov.info
    fail_ci_if_error: true

Common gotchas

  • Forked PRs do not get secrets, so token-less uploads can hit rate limits - use tokenless OIDC or the Codecov GitHub App.
  • If coverage is empty, your test command probably did not actually write a report - check the path with ls before uploading.
  • fail_ci_if_error: true is off by default, so silent upload failures look green.

Key takeaways

  • Codecov needs a report file from your test step plus the codecov-action.
  • Set CODECOV_TOKEN even on public repos to dodge rate limits.
  • Forked PRs cannot read secrets - use the Codecov GitHub App or OIDC.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →