JavaScript and TypeScript coverage
Use Jest or Vitest to generate LCOV, then upload coverage/lcov.info from GitHub Actions.
Install dependencies
Jest and Vitest both emit LCOV. Use the package manager your project already uses.
npm install --save-dev jest
pnpm add -D vitest
yarn add --dev vitest
Generate coverage
Make sure your test script writes LCOV to coverage/lcov.info.
npm test -- --coverage --coverageReporters=lcov
pnpm vitest run --coverage
yarn vitest run --coverage
GitHub Actions workflow
Add COVERAGE_UPLOAD_TOKEN as an organization or repository secret. The action uses the default upload endpoint unless you provide an optional endpoint override.
name: coverage
on:
pull_request:
push:
jobs:
coverage:
if: github.event_name == 'pull_request' || github.ref_name == github.event.repository.default_branch
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm test -- --coverage --coverageReporters=lcov
- name: Upload coverage
uses: 9to5/9to5-coverage-action@v1
with:
token: ${{ secrets.COVERAGE_UPLOAD_TOKEN }}
path: coverage/lcov.info
Pull request behavior
9to5 coverage posts project and patch checks to the uploaded commit and comments when changed lines are uncovered.
Troubleshooting
If the upload says the file is missing, confirm the test command created coverage/lcov.info. If authentication fails, rotate the upload token and update the GitHub secret.