Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions .github/workflows/check-abi-comment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
name: Check ABI Comment

# Posts the result of the "Check ABI" workflow back onto the pull request.
# Because it is triggered by workflow_run it runs in the base repository
# context with a writable token, so it can comment on fork PRs without ever
# checking out or executing untrusted PR code.
#
# One comment per PR is created on the first run and updated in place after.
#
# NOTE: workflow_run only triggers from workflow files on the default branch, so
# this begins working once merged to master.

on:
workflow_run:
workflows: [Check ABI]
types: [completed]

permissions:
actions: read # download the summary artifacts from the triggering run
contents: read
pull-requests: write # comment on the pull request (issues API, PR target)

jobs:
comment:
runs-on: ubuntu-latest
if: >-
github.event.workflow_run.event == 'pull_request' ||
github.event.workflow_run.event == 'pull_request_review'
steps:
- name: Download summaries
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
continue-on-error: true
with:
pattern: abi-summary-*
merge-multiple: true
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Post or update PR comment
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
RUN_URL: ${{ github.event.workflow_run.html_url }}
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
with:
script: |
const fs = require('fs');
const marker = '<!-- check-abi-report -->';
const { owner, repo } = context.repo;

if (!fs.existsSync('pr_number.txt')) {
core.info('No summary artifact found; nothing to comment on.');
return;
}
const issue_number = parseInt(fs.readFileSync('pr_number.txt', 'utf8').trim(), 10);
if (!Number.isInteger(issue_number)) {
core.info('Invalid PR number; skipping.');
return;
}
// The artifact comes from PR-controlled code; only trust the number if
// that PR's head is the commit the run checked.
const { data: pr } = await github.rest.pulls.get({ owner, repo, pull_number: issue_number });
if (pr.head.sha !== process.env.HEAD_SHA) {
core.info(`PR #${issue_number} head is ${pr.head.sha}, run checked ${process.env.HEAD_SHA}; skipping.`);
return;
}

const sections = ['last-release', 'master']
.filter(base => fs.existsSync(`${base}.md`))
.map(base => fs.readFileSync(`${base}.md`, 'utf8').trim());

const body = [
marker,
'### Level Zero loader ABI check',
'',
...sections.flatMap(s => [s, '']),
`[Workflow run](${process.env.RUN_URL})`,
'',
'If an ABI change is intended, a reviewer with write access can accept it: '
+ 'leave an **approval review** on the PR head commit with the keyword '
+ '`abi-failure-approved` in the review body. That re-runs the check.',
].join('\n');

const comments = await github.paginate(github.rest.issues.listComments, {
owner, repo, issue_number, per_page: 100,
});
const existing = comments.find(c => c.body && 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 });
}
Loading
Loading