snapshot of https://github.com/RocketChat/Rocket.Chat.git (develop, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 2s
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 2s
This commit is contained in:
125
docs/coverage.md
Normal file
125
docs/coverage.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# Code Coverage
|
||||
|
||||
This document explains how code coverage instrumentation works in Rocket.Chat's build and CI pipeline.
|
||||
|
||||
## Overview
|
||||
|
||||
Coverage is collected during E2E test runs (API, UI, Livechat) to measure how much of the server-side code is exercised by tests. The instrumentation uses [Istanbul](https://istanbul.js.org/)-compatible tooling, which injects counters (`__coverage__`) into the compiled code at build time.
|
||||
|
||||
## Architecture
|
||||
|
||||
The coverage pipeline has three components:
|
||||
|
||||
1. **Build-time instrumentation** - injects coverage counters into the code during Meteor build
|
||||
2. **Runtime collection** - the `rocketchat:coverage` Meteor package collects `__coverage__` data on process exit
|
||||
3. **CI reporting** - test workflows merge coverage data and upload reports
|
||||
|
||||
```
|
||||
Build (SWC + plugin) --> Run tests --> Process exit triggers report --> Merge & upload
|
||||
```
|
||||
|
||||
## Build-time instrumentation
|
||||
|
||||
### Modern build stack (SWC)
|
||||
|
||||
Rocket.Chat uses Meteor's modern build stack with [SWC](https://swc.rs/) as the transpiler. For coverage builds, the [`swc-plugin-coverage-instrument`](https://github.com/kwonoj/swc-plugin-coverage-instrument) plugin is injected into `.swcrc` at build time.
|
||||
|
||||
This is configured in `.github/actions/meteor-build/action.yml`:
|
||||
|
||||
```yaml
|
||||
env:
|
||||
BABEL_ENV: ${{ inputs.type }} # "production" or "coverage"
|
||||
```
|
||||
|
||||
When `BABEL_ENV=coverage`, the build script:
|
||||
|
||||
1. Adds `rocketchat:coverage` to `.meteor/packages`
|
||||
2. Injects `swc-plugin-coverage-instrument` into `.swcrc` via a node script:
|
||||
|
||||
```js
|
||||
const swcrc = JSON.parse(fs.readFileSync('./apps/meteor/.swcrc', 'utf8'));
|
||||
swcrc.jsc.experimental = swcrc.jsc.experimental || {};
|
||||
swcrc.jsc.experimental.plugins = swcrc.jsc.experimental.plugins || [];
|
||||
swcrc.jsc.experimental.plugins.push(['swc-plugin-coverage-instrument', {}]);
|
||||
fs.writeFileSync('./apps/meteor/.swcrc', JSON.stringify(swcrc, null, 2) + '\n');
|
||||
```
|
||||
|
||||
This approach ensures the same build pipeline (SWC) is used for both regular and coverage builds, avoiding behavioral differences between build modes.
|
||||
|
||||
### Legacy build stack (Babel)
|
||||
|
||||
Before the modern build stack, coverage was handled via `babel-plugin-istanbul` configured in `.babelrc`:
|
||||
|
||||
```json
|
||||
{
|
||||
"env": {
|
||||
"coverage": {
|
||||
"plugins": [
|
||||
["istanbul", { "exclude": ["**/*.spec.js", "**/*.test.js"] }]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This section is still present in `.babelrc` as a fallback for files that fall back to Babel compilation (e.g., SWC-incompatible code).
|
||||
|
||||
## Runtime collection: `rocketchat:coverage`
|
||||
|
||||
The `rocketchat:coverage` Meteor package (`apps/meteor/packages/rocketchat-coverage/`) is only added to the build during coverage runs. It:
|
||||
|
||||
1. Registers a `process.on('exit')` handler
|
||||
2. Reads `globalThis['__coverage__']` (populated by the instrumentation)
|
||||
3. Generates a coverage report using `istanbul-lib-coverage` and `istanbul-reports`
|
||||
|
||||
Configuration via environment variables:
|
||||
|
||||
| Variable | Description | Example |
|
||||
|---|---|---|
|
||||
| `COVERAGE_DIR` | Output directory for reports | `/tmp/coverage/api` |
|
||||
| `COVERAGE_FILE_NAME` | Report filename | `api-1.json` |
|
||||
| `COVERAGE_REPORTER` | Istanbul reporter format | `json`, `lcov` |
|
||||
|
||||
## CI workflow
|
||||
|
||||
Coverage is collected in the `ci-test-e2e.yml` workflow:
|
||||
|
||||
1. **Build**: `meteor-build` action runs with `type: coverage`, producing a Docker image with instrumented code
|
||||
2. **Test**: E2E tests run against the instrumented server. On each test shard:
|
||||
- `COVERAGE_DIR`, `COVERAGE_FILE_NAME`, and `COVERAGE_REPORTER` are set
|
||||
- When the Rocket.Chat process exits after tests, the coverage plugin writes a JSON report
|
||||
3. **Merge**: `nyc merge` combines per-shard JSON reports into a single coverage file
|
||||
4. **Upload**: Coverage data is uploaded to Codecov
|
||||
|
||||
## Local development
|
||||
|
||||
To build with coverage locally:
|
||||
|
||||
```bash
|
||||
cd apps/meteor
|
||||
|
||||
# Inject the SWC coverage plugin into .swcrc
|
||||
node -e "
|
||||
const fs = require('fs');
|
||||
const swcrc = JSON.parse(fs.readFileSync('.swcrc', 'utf8'));
|
||||
swcrc.jsc.experimental = { plugins: [['swc-plugin-coverage-instrument', {}]] };
|
||||
fs.writeFileSync('.swcrc', JSON.stringify(swcrc, null, 2));
|
||||
"
|
||||
|
||||
# Add the coverage package
|
||||
echo -e "rocketchat:coverage\n" >> .meteor/packages
|
||||
|
||||
# Set env vars and run
|
||||
COVERAGE_DIR=/tmp/coverage COVERAGE_FILE_NAME=local.json COVERAGE_REPORTER=lcov yarn dev
|
||||
```
|
||||
|
||||
Remember to restore `.swcrc` and `.meteor/packages` after testing.
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Package | Purpose |
|
||||
|---|---|
|
||||
| `swc-plugin-coverage-instrument` | SWC plugin for Istanbul-compatible instrumentation |
|
||||
| `istanbul-lib-coverage` | Coverage map creation (used by `rocketchat:coverage`) |
|
||||
| `istanbul-lib-report` | Report context creation |
|
||||
| `istanbul-reports` | Report formatters (json, lcov, etc.) |
|
||||
Reference in New Issue
Block a user