name: PR Comments
on:
workflow_run:
workflows: ["CI"]
types:
- completed
permissions:
pull-requests: write
contents: read
jobs:
comment:
name: Post PR comments
runs-on: ubuntu-latest
if: github.event.workflow_run.event == 'pull_request'
steps:
- name: Download CI artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 with:
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
path: artifacts
continue-on-error: true
- name: Post benchmark and coverage comments
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b env:
TRUSTED_PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number }}
with:
script: |
const fs = require('fs');
const prNumber = parseInt(process.env.TRUSTED_PR_NUMBER, 10);
if (!Number.isInteger(prNumber) || prNumber <= 0) {
console.log('No trusted PR number on the workflow_run event; skipping comments.');
return;
}
// Reads an artifact JSON file if it was downloaded, else null.
function readResults(name) {
const path = `artifacts/${name}/${name}.json`;
if (!fs.existsSync(path)) {
console.log(`No ${name} artifact found; skipping.`);
return null;
}
return JSON.parse(fs.readFileSync(path, 'utf8'));
}
// Parses an artifact-supplied numeric field. Returns null for any
// value that is not a finite number so untrusted content can never
// reach the comment body verbatim.
function finiteOrNull(value) {
const n = parseFloat(value);
return Number.isFinite(n) ? n : null;
}
// Creates a new comment or updates the existing bot comment that
// contains `marker` in its body.
async function upsertComment(prNumber, marker, body) {
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
});
const botComment = comments.find(c =>
c.user.type === 'Bot' && c.body.includes(marker)
);
if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body,
});
}
}
const benchmark = readResults('benchmark-results');
if (benchmark) {
const currentScore = finiteOrNull(benchmark.currentScore);
const baselineScore = finiteOrNull(benchmark.baselineScore);
if (currentScore === null) {
console.log('Benchmark artifact has no valid currentScore; skipping.');
} else {
let comment = '## CoreMark Benchmark Results\n\n';
comment += `**Current Score:** ${currentScore.toFixed(3)}\n`;
if (baselineScore !== null) {
const diff = currentScore - baselineScore;
const percentChange = ((diff / baselineScore) * 100).toFixed(2);
comment += `**Baseline Score (main):** ${baselineScore.toFixed(3)}\n`;
comment += `**Difference:** ${diff >= 0 ? '+' : ''}${diff.toFixed(3)} (${percentChange}%)\n\n`;
} else {
comment += '\n_No baseline available for comparison_\n';
}
await upsertComment(
prNumber,
'CoreMark Benchmark Results',
comment
);
}
}
const coverage = readResults('coverage-results');
if (coverage) {
const currentCoverage = finiteOrNull(coverage.currentCoverage);
const baselineCoverage = finiteOrNull(coverage.baselineCoverage);
if (currentCoverage === null) {
console.log('Coverage artifact has no valid currentCoverage; skipping.');
} else {
let comment = '## Code Coverage Report\n\n';
comment += `**Current Coverage:** ${currentCoverage.toFixed(2)}%\n`;
if (baselineCoverage !== null) {
const diff = currentCoverage - baselineCoverage;
comment += `**Baseline Coverage (main):** ${baselineCoverage.toFixed(2)}%\n`;
comment += `**Difference:** ${diff >= 0 ? '+' : ''}${diff.toFixed(2)}%\n\n`;
if (diff < -1.0) {
comment += '**Warning:** Coverage decreased by more than 1%\n';
} else if (diff >= 1.0) {
comment += '**Improvement:** Coverage increased!\n';
}
} else {
comment += '\n_No baseline available for comparison_\n';
}
await upsertComment(
prNumber,
'Code Coverage Report',
comment
);
}
}