chore(readme): add dynamic coverage badge

This commit is contained in:
Tommaso Casaburi
2026-03-16 20:55:01 +08:00
parent 81f67ee287
commit d08becf4b2
4 changed files with 96 additions and 0 deletions
+38
View File
@@ -44,6 +44,18 @@ jobs:
- name: Collect coverage
run: yarn test:coverage
- name: Write coverage badge payload
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
run: node scripts/write-coverage-badge.mjs
- name: Upload coverage badge
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/upload-artifact@v4
with:
name: coverage-badge
path: badges/coverage.json
if-no-files-found: error
- name: Lint
run: yarn lint
@@ -84,6 +96,32 @@ jobs:
path: coverage/coverage-summary.json
if-no-files-found: warn
publish-coverage-badge:
name: Publish Coverage Badge
runs-on: ubuntu-22.04
needs: quality
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.ref_name }}
- name: Download coverage badge
uses: actions/download-artifact@v4
with:
name: coverage-badge
path: badges/
- run: git add badges/coverage.json
- run: git status
- uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: 'chore(ci): update coverage badge'
file_pattern: 'badges/coverage.json'
branch: ${{ github.ref_name }}
android-build:
name: Android Build
runs-on: ubuntu-22.04
+1
View File
@@ -1,4 +1,5 @@
[![Build Status](https://img.shields.io/github/actions/workflow/status/bitsocialnet/5chan/ci.yml?branch=master)](https://github.com/bitsocialnet/5chan/actions/workflows/ci.yml)
[![Coverage](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/bitsocialnet/5chan/master/badges/coverage.json)](https://github.com/bitsocialnet/5chan/actions/workflows/ci.yml)
[![Release](https://img.shields.io/github/v/release/bitsocialnet/5chan)](https://github.com/bitsocialnet/5chan/releases/latest)
[![License](https://img.shields.io/badge/license-GPL--2.0--only-red.svg)](https://github.com/bitsocialnet/5chan/blob/master/LICENSE)
[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
+6
View File
@@ -0,0 +1,6 @@
{
"schemaVersion": 1,
"label": "coverage",
"message": "pending",
"color": "lightgrey"
}
+51
View File
@@ -0,0 +1,51 @@
import fs from "fs";
import path from "path";
const CWD = process.cwd();
const COVERAGE_SUMMARY_PATHS = [
path.join(CWD, "coverage", "coverage-summary.json"),
path.join(CWD, "src", "coverage", "coverage-summary.json"),
];
const BADGE_OUTPUT_PATH = path.join(CWD, "badges", "coverage.json");
const coverageSummaryPath = COVERAGE_SUMMARY_PATHS.find((candidate) => fs.existsSync(candidate));
if (!coverageSummaryPath) {
const checkedPaths = COVERAGE_SUMMARY_PATHS.map((candidate) => `"${candidate}"`).join(", ");
console.error(`[coverage-badge] Missing coverage summary. Checked: ${checkedPaths}.`);
process.exit(1);
}
const summary = JSON.parse(fs.readFileSync(coverageSummaryPath, "utf8"));
const lineCoveragePct = summary?.total?.lines?.pct;
if (typeof lineCoveragePct !== "number") {
console.error(`[coverage-badge] Missing total.lines.pct in "${coverageSummaryPath}".`);
process.exit(1);
}
const roundedPct = Number(lineCoveragePct.toFixed(1));
const color =
lineCoveragePct >= 95
? "brightgreen"
: lineCoveragePct >= 90
? "green"
: lineCoveragePct >= 80
? "yellowgreen"
: lineCoveragePct >= 70
? "yellow"
: lineCoveragePct >= 60
? "orange"
: "red";
const badge = {
schemaVersion: 1,
label: "coverage",
message: `${roundedPct}%`,
color,
};
fs.mkdirSync(path.dirname(BADGE_OUTPUT_PATH), { recursive: true });
fs.writeFileSync(BADGE_OUTPUT_PATH, `${JSON.stringify(badge, null, 2)}\n`);
console.log(
`[coverage-badge] Wrote "${BADGE_OUTPUT_PATH}" from "${coverageSummaryPath}" (${roundedPct}%).`,
);