Skip to content

Frontend Coverage Comment #4

Frontend Coverage Comment

Frontend Coverage Comment #4

name: Frontend Coverage Comment
# Runs in the base repo's context (not the PR head's), so it gets a
# write-capable GITHUB_TOKEN even for PRs from forks. It never checks out
# or executes any code from the PR — it only downloads the small JSON
# artifact produced by the `build` job in frontend.yml and posts/updates a
# PR comment from it.
on:
workflow_run:
workflows: ["Frontend CI"]
types: [completed]
permissions:
contents: read
pull-requests: write
jobs:
comment:
name: Post coverage comment
runs-on: ubuntu-latest
if: github.event.workflow_run.event == 'pull_request'
steps:
- name: Download coverage report artifact
id: download
continue-on-error: true
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: frontend-coverage-report
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Post or update comment
if: steps.download.outcome == 'success'
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
with:
script: |
const fs = require('fs');
const report = JSON.parse(fs.readFileSync('frontend-coverage-report.json', 'utf8'));
const marker = '<!-- frontend-coverage-report -->';
const row = (label, pct, target) => {
const status = pct >= target ? '✅' : '⚠️';
return `| ${label} | ${pct.toFixed(2)}% | ${target}% | ${status} |`;
};
const body = [
marker,
'### Frontend unit test coverage',
'',
`Commit \`${report.head_sha.slice(0, 7)}\``,
'',
'| Metric | Coverage | Target | |',
'|---|---|---|---|',
row('Statements', report.statements, report.targets.statements),
row('Branches', report.branches, report.targets.branches),
row('Functions', report.functions, report.targets.functions),
row('Lines', report.lines, report.targets.lines),
'',
'_Targets are informational — not currently enforced as a CI gate._',
].join('\n');
const { owner, repo } = context.repo;
const issue_number = report.pr_number;
const comments = await github.rest.issues.listComments({ owner, repo, issue_number });
const existing = comments.data.find((c) => c.body.includes(marker));
if (existing) {
await github.rest.issues.updateComment({ owner, repo, comment_id: existing.id, body });
} else {
await github.rest.issues.createComment({ owner, repo, issue_number, body });
}