Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Coverage

on:
pull_request:
branches:
- main

jobs:
coverage:
runs-on: ubuntu-latest
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Required for turbo diff

- name: Setup pnpm
uses: pnpm/action-setup@v3
with:
version: 10

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22
cache: "pnpm"
cache-dependency-path: "**/pnpm-lock.yaml"

- name: Install dependencies
run: pnpm install --frozen-lockfile

# --- PR coverage (affected only) ---
- name: Run PR coverage
# the filter means 'projects changed since origin/main, inc dependents'
run: pnpm turbo coverage --filter=...[origin/main] --force --no-daemon

- name: Save PR coverage
run: |
mkdir pr-coverage
find . -name coverage-summary.json | while read file; do
project=$(dirname "$(dirname "$file")")
project=$(basename "$project")
cp "$file" "pr-coverage/$project.json"
done

- name: Capture PR ref
run: echo "PR_REF=${{ github.head_ref }}" >> $GITHUB_ENV

# --- baseline coverage ---
- name: Checkout main
run: git checkout origin/main

- name: Install dependencies (main)
run: pnpm install --frozen-lockfile

- name: Run coverage (main affected)
# notice both times we --force turbo to ignore cache and execute tasks fresh
run: pnpm turbo coverage --filter=...[origin/$PR_REF] --force --no-daemon

- name: Save coverage (main affected)
run: |
mkdir base-coverage
find . -name coverage-summary.json | while read file; do
project=$(dirname "$(dirname "$file")")
project=$(basename "$project")
cp "$file" "base-coverage/$project.json"
done

# --- compare ---
- name: Compare coverage
# the script errors (exit code 1), causing this action to fail,
# if regression for any app or package is detected
run: node scripts/compare-coverage.mjs pr-coverage base-coverage
43 changes: 43 additions & 0 deletions scripts/compare-coverage.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import fs from "node:fs";

const prDir = process.argv[2];
const baseDir = process.argv[3];

const projects = fs.readdirSync(prDir).filter((file) => file.endsWith(".json"));

let failed = false;

for (const file of projects) {
const prPath = `${prDir}/${file}`;
const basePath = `${baseDir}/${file}`;

if (!fs.existsSync(basePath)) {
console.log(`⚠️ ${file.replace(".json", "")}: no baseline found, skipping`);
continue;
}

const pr = JSON.parse(fs.readFileSync(prPath));
const base = JSON.parse(fs.readFileSync(basePath));

const prLines = pr.total.lines.pct;
const baseLines = base.total.lines.pct;

const delta = (prLines - baseLines).toFixed(2);
const name = file.replace(".json", "");

console.log(`\nProject: ${name}`);
console.log(`Base: ${baseLines}%`);
console.log(`PR: ${prLines}%`);
console.log(`Δ: ${delta}%`);

if (prLines < baseLines) {
console.log("❌ Regression detected");
failed = true;
} else {
console.log("✅ OK");
}
}

if (failed) {
process.exit(1);
}
Loading