Skip to content

PR Test Summary Comment #3

PR Test Summary Comment

PR Test Summary Comment #3

name: PR Test Summary Comment
on:
workflow_run:
workflows: ["Test"]
types: [completed]
permissions:
contents: read
actions: read
issues: write
pull-requests: write
jobs:
comment:
name: Comment test summary on PR
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.event == 'pull_request' }}
steps:
- name: Download summary artifact
continue-on-error: true
uses: actions/download-artifact@v4
with:
name: ci-test-summary
path: ./ci-summary
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Resolve PR number
id: resolve_pr
uses: actions/github-script@v7
with:
script: |
const run = context.payload.workflow_run;
const owner = context.repo.owner;
const repo = context.repo.repo;
function resolved(prNumber, source) {
const value = String(prNumber);
core.info(`Resolved PR #${value} via ${source}.`);
core.setOutput('pr_number', value);
}
function unresolved(reason) {
core.info(`No PR resolved: ${reason}`);
core.setOutput('pr_number', '');
}
const payloadPr = run.pull_requests?.[0]?.number;
if (payloadPr) {
resolved(payloadPr, 'workflow payload');
return;
}
if (run.head_sha) {
try {
const associated = await github.rest.repos.listPullRequestsAssociatedWithCommit({
owner,
repo,
commit_sha: run.head_sha,
});
const openPr = associated.data.find((pr) => pr.state === 'open');
const commitPr = openPr?.number || associated.data[0]?.number;
if (commitPr) {
resolved(commitPr, 'commit SHA association');
return;
}
} catch (error) {
core.info(`Commit SHA association lookup failed: ${error.message}`);
}
} else {
core.info('Skipping commit SHA association lookup (no head SHA).');
}
const headOwner = run.head_repository?.owner?.login;
const headBranch = run.head_branch;
if (headOwner && headBranch) {
try {
const byHead = await github.rest.pulls.list({
owner,
repo,
state: 'open',
head: `${headOwner}:${headBranch}`,
per_page: 1,
});
const headPr = byHead.data[0]?.number;
if (headPr) {
resolved(headPr, 'head repo/branch');
return;
}
} catch (error) {
core.info(`Head repo/branch lookup failed: ${error.message}`);
}
} else {
core.info('Skipping head repo/branch lookup (missing head owner or branch).');
}
unresolved('workflow payload, commit SHA, and head repo/branch lookups all failed.');
- name: Create or update PR comment
if: ${{ steps.resolve_pr.outputs.pr_number != '' }}
env:
PR_NUMBER: ${{ steps.resolve_pr.outputs.pr_number }}
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const marker = '<!-- ci-test-summary -->';
const owner = context.repo.owner;
const repo = context.repo.repo;
const issue_number = Number(process.env.PR_NUMBER);
const summaryPath = 'ci-summary/ci-test-summary.md';
if (!fs.existsSync(summaryPath)) {
core.info(`Summary artifact file not found at ${summaryPath}.`);
return;
}
const summaryMarkdown = fs.readFileSync(summaryPath, 'utf8').trim();
const body = `${marker}\n${summaryMarkdown}`;
const comments = await github.paginate(github.rest.issues.listComments, {
owner,
repo,
issue_number,
per_page: 100,
});
const existing = comments.find(
(comment) =>
comment.user &&
comment.user.login === 'github-actions[bot]' &&
typeof comment.body === 'string' &&
comment.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,
});
}
- name: Log unresolved PR
if: ${{ steps.resolve_pr.outputs.pr_number == '' }}
run: echo "No pull request could be resolved. Skipping comment."