Documentation

Migrate from Codecov

Keep generating coverage in CI. Put tested.dev on the PR. Require the job. Then Codecov comes out.

1. What you already have

  • Node 24+.
  • Tests that write coverage. Vitest/Jest default is Istanbul/V8 coverage/coverage-final.json. The CLI also reads lcov, Cobertura, JaCoCo, gcov text, and SimpleCov. Set coverage.pathif it isn't the default file.

Keep the test step. Full path: Install. CI: GitHub Action.

2. Install

pnpm add -D @tested/cli
tested setup
# writes .tested.yaml
# runs doctor (Node 24+, git, config, coverage path, origin)

Local tested diff / tested check need no account, no token. Same for the Action with push default false.

3. Thresholds

Floors live in .tested.yaml. The Action has no threshold inputs. Fields: Config.

# .tested.yaml
base: origin/main
testRunner: pnpm test -- --coverage
thresholds:
  patch: 80   # new executable lines
  project: 60 # overall floor
  paths:
    - glob: src/api/**
      patch: 90
      project: 90
    - glob: src/cli/**
      patch: 70
      project: 70

Optional thresholds.paths: independent floors per glob. Omitted patch / project inherit the global floors. A glob with no files this run is skipped (not 0%). Not flags. tested check fails when any matched path is under its floor. Coverage stays the only PR gate.

If codecov.yml has flags, put them here. tested check and tested push grade each package from this run.

flags:
  frontend:
    paths: ["apps/web/**", "packages/ui/**"]
    thresholds:
      patch: 90
  backend:
    paths: ["apps/api/**"]

A job already scoped to one package: Action flag: frontend.

4. GitHub Action

Gate: no account, no token. Pin uses: to a SHA in production. Same snippet as GitHub Action.

# .github/workflows/tested.yml
name: tested
on:
  pull_request:
jobs:
  coverage:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 24
          cache: pnpm
      - run: pnpm install --frozen-lockfile
      - run: pnpm test -- --coverage
      - uses: tested-hq/cli/action@main   # pin uses: to a SHA in production
        with:
          version: 0.1.10

Share / push: install tested-dev-app, mint TESTED_TOKEN. The project page is /repos/{owner}/{name} — 30-day mainline coverage and the PRs. push: true on the PR. mainline: true on default branch. Inputs on GitHub Action.

- uses: tested-hq/cli/action@main   # pin uses: to a SHA in production
  with:
    version: 0.1.10
    push: 'true'
    pr-number: ${{ github.event.pull_request.number }}
    token: ${{ secrets.TESTED_TOKEN }}

If CI writes more than one coverage file, list them in coverage.path or Action files. The CLI merges them and checks once.

5. Require, then remove Codecov

  1. Require the job

    Open a PR so coverage runs once. Repo Settings → Branches → require status checks → add coverage.

Delete Codecov

  • Codecov Action step
  • codecov.yml
  • CODECOV_TOKEN
  • Required codecov/* checks
  • Codecov badge. Last: the tested.dev badge.
[![tested](https://app.tested.dev/badge/{owner}/{name})](https://app.tested.dev/repos/{owner}/{name})

Done when tested doctor is clean and that job is the required check.

6. Verify

tested doctor
# No FAIL. WARN is fine if you know why.

The coverage job posts a conclusion. With push: true, the log has a share URL. If it fails: Troubleshooting.