{"id":50784046,"url":"https://github.com/kshutkin/github-action-coverage-badge","last_synced_at":"2026-06-12T06:05:24.748Z","repository":{"id":353790451,"uuid":"1220917110","full_name":"kshutkin/github-action-coverage-badge","owner":"kshutkin","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-25T14:16:20.000Z","size":26,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-25T16:17:58.119Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kshutkin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-25T14:06:39.000Z","updated_at":"2026-04-25T14:16:23.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/kshutkin/github-action-coverage-badge","commit_stats":null,"previous_names":["kshutkin/github-action-coverage-badge"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/kshutkin/github-action-coverage-badge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kshutkin%2Fgithub-action-coverage-badge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kshutkin%2Fgithub-action-coverage-badge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kshutkin%2Fgithub-action-coverage-badge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kshutkin%2Fgithub-action-coverage-badge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kshutkin","download_url":"https://codeload.github.com/kshutkin/github-action-coverage-badge/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kshutkin%2Fgithub-action-coverage-badge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34231236,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-12T02:00:06.859Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-12T06:05:20.104Z","updated_at":"2026-06-12T06:05:24.742Z","avatar_url":"https://github.com/kshutkin.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# github-action-coverage-badge\n\nA GitHub Action that discovers coverage reports anywhere in your repository, generates a self-contained SVG badge per report, and force-pushes the badges together with the original coverage folders to a configurable orphan branch (default `coverage`). You then reference the badges from your `README.md` using the `raw.githubusercontent.com` URL.\n\n- No build step, no committed `dist/`. Pure ESM JS with JSDoc types.\n- Zero runtime dependencies — runs on the default `node20` runtime.\n- Bun is used **only for development and tests** (`bun test`).\n- Self-contained Shields.io-flat SVGs (no external network calls at runtime).\n- Designed to drop into a reusable workflow (e.g. the sibling [`pipeline`](https://github.com/kshutkin/pipeline) repo).\n\n## Supported coverage formats\n\nDetected in this priority order (first match wins per coverage folder):\n\n| Priority | Filename | Producer examples |\n| --- | --- | --- |\n| 1 | `coverage-summary.json` | Istanbul (`json-summary` reporter) |\n| 2 | `coverage-final.json` | Istanbul / Vitest (`v8` provider, default JSON reporter) |\n| 3 | `lcov.info` | nyc, c8, jest |\n| 4 | `clover.xml` | Vitest (default `v8` clover reporter), nyc |\n| 5 | `cobertura-coverage.xml` | jest, nyc |\n\nFor each folder the action computes four metrics — `lines`, `statements`, `branches`, `functions` — and renders one badge using whichever metric you select.\n\n## Quickstart\n\n```yaml\n# .github/workflows/coverage-badges.yml\nname: Coverage badges\non:\n    push:\n        branches: [main]\n\njobs:\n    badges:\n        runs-on: ubuntu-latest\n        permissions:\n            contents: write\n        steps:\n            - uses: actions/checkout@v4\n              with:\n                  fetch-depth: 0\n            - run: pnpm install --frozen-lockfile\n            - run: pnpm test # produces coverage/ folders\n            - uses: kshutkin/github-action-coverage-badge@v1\n```\n\nAfter the first successful run, your repo will have a `coverage` branch with this layout (mirroring the source tree):\n\n```\nplugin-clean/\n    badge.svg\n    coverage/\n        coverage-final.json\n        clover.xml\n        index.html\n        ...\nplugin-utils/\n    badge.svg\n    coverage/...\nREADME.md   # auto-generated index\n```\n\nReference a badge from your main `README.md`:\n\n```markdown\n![coverage](https://raw.githubusercontent.com/\u003cowner\u003e/\u003crepo\u003e/coverage/plugin-clean/badge.svg)\n```\n\n## Inputs\n\n| Name | Default | Description |\n| --- | --- | --- |\n| `branch` | `coverage` | Orphan branch the action force-pushes to. |\n| `coverage-paths` | `**/coverage` | Comma- or newline-separated globs of coverage folders. Supports `**`, `*`, `?`, `{a,b}`. |\n| `ignore` | `**/node_modules/**` | Comma- or newline-separated globs to skip during discovery. |\n| `metric` | `branches` | One of `lines`, `statements`, `branches`, `functions`. |\n| `label` | `coverage` | Left-side label text on the badge. |\n| `thresholds` | `50:red,60:orange,70:yellow,80:yellowgreen,90:green,100:brightgreen` | Comma-separated `\u003cupTo\u003e:\u003ccolor\u003e` pairs. The first bucket whose `upTo \u003e= pct` wins. Colors can be one of `brightgreen`, `green`, `yellowgreen`, `yellow`, `orange`, `red`, `blue`, `lightgrey`, `grey`, or any `#rrggbb` / `#rgb` hex. |\n| `precision` | `0` | Decimal places shown on the percentage (0..6). |\n| `style` | `flat` | Reserved. Only `flat` is supported in v1. |\n| `commit-message` | `chore: update coverage badges` | Commit message for the orphan branch commit. |\n| `commit-user-name` | `github-actions[bot]` | Git user name for the commit. |\n| `commit-user-email` | `41898282+github-actions[bot]@users.noreply.github.com` | Git user email. |\n| `token` | `${{ github.token }}` | Token used to push the orphan branch. Requires `contents: write`. |\n| `dry-run` | `false` | If `true`, badges are written into `.coverage-badge-out/` next to the workspace and nothing is pushed. |\n\n## Outputs\n\n| Name | Description |\n| --- | --- |\n| `branch` | The branch badges were pushed to. |\n| `commit-sha` | SHA of the new commit on the orphan branch (empty on dry-run). |\n| `badges-json` | JSON array `[{ path, metric, pct, color, format }]` describing every badge generated. |\n\n## Custom thresholds\n\nThreshold buckets are evaluated in ascending order; each bucket is the upper bound (inclusive) for the previous one. So:\n\n```\nthresholds: 60:red,80:yellow,100:brightgreen\n```\n\nmeans:\n- `pct ≤ 60` → red\n- `60 \u003c pct ≤ 80` → yellow\n- `80 \u003c pct ≤ 100` → brightgreen\n- anything \u003e 100 falls back to the last bucket (brightgreen).\n\n## Permissions\n\nThe job that uses this action must have `contents: write`:\n\n```yaml\npermissions:\n    contents: write\n```\n\n## Output layout\n\nFor every discovered coverage folder, the badge is written **as a sibling** of that folder, preserving the source repo's path. This avoids any monorepo conventions and prevents filename collisions: each badge sits in its own directory.\n\nA discovered folder at `pkg-a/coverage/` produces:\n- `pkg-a/badge.svg` (the badge)\n- `pkg-a/coverage/...` (the original coverage report files)\n\nA top-level `README.md` is also generated on the orphan branch listing every badge.\n\n## Local dry-run\n\nValidate from any repo with coverage folders:\n\n```sh\nINPUT_DRY_RUN=true GITHUB_WORKSPACE=\"$PWD\" \\\n  node /path/to/github-action-coverage-badge/src/main.js\n```\n\nBadges are written under `.coverage-badge-out/` mirroring the discovered layout.\n\n## Development\n\n```sh\nbun install\nbun test\nbunx tsc -p .   # JSDoc type-check\n```\n\n## Troubleshooting\n\n- **No coverage folders found.** Confirm `coverage-paths` matches your layout and that test scripts ran before this action. Check the action log — every candidate folder is logged.\n- **`Permission denied` on push.** The workflow needs `permissions: contents: write` and the default `GITHUB_TOKEN` must not be restricted by repo settings.\n- **Wrong percentage.** Detection prefers `coverage-summary.json` over detailed forms. If you see different numbers than expected, check the format selected in the action log; you can disable the summary by deleting it before running, or switch metrics with the `metric` input.\n- **Badge looks broken.** SVGs use Verdana metrics; if your label is unusually long the rendered width is approximated and may slightly clip. Open an issue with the input/output if this is a problem in practice.\n\n## License\n\nMIT — see [LICENSE](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkshutkin%2Fgithub-action-coverage-badge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkshutkin%2Fgithub-action-coverage-badge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkshutkin%2Fgithub-action-coverage-badge/lists"}