mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-15 23:31:07 +00:00
The workflow resolved the PR from workflow_run.pull_requests or the head commit, both of which come back empty for PRs from forks — so it logged "No open PR for this build" and never commented. Resolve the PR by its head "owner:branch" (from workflow_run.head_repository/head_branch), which works for forks, keeping the commit-association path as a fallback.
121 lines
4.9 KiB
YAML
121 lines
4.9 KiB
YAML
# Copyright (C) 2026 SharpEmu Emulator Project
|
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
# Posts (and keeps updated) a single PR comment linking the per-platform build
|
|
# artifacts once "Build and Release" finishes.
|
|
#
|
|
# This is a workflow_run workflow on purpose: PRs from forks run "Build and
|
|
# Release" with a read-only GITHUB_TOKEN and cannot comment. workflow_run runs
|
|
# afterwards in the base-repo context with a read-write token and does not check
|
|
# out untrusted fork code, so it can comment safely. Because of that, GitHub only
|
|
# triggers it from the copy on the default branch — it does nothing until merged
|
|
# to main.
|
|
name: PR Build Links
|
|
|
|
on:
|
|
workflow_run:
|
|
workflows: ["Build and Release"]
|
|
types:
|
|
- completed
|
|
|
|
permissions:
|
|
contents: read
|
|
actions: read
|
|
pull-requests: write
|
|
|
|
jobs:
|
|
comment:
|
|
name: Post artifact links
|
|
runs-on: ubuntu-latest
|
|
# Only for successful PR builds — artifacts exist only when the build passed.
|
|
if: >-
|
|
github.event.workflow_run.event == 'pull_request' &&
|
|
github.event.workflow_run.conclusion == 'success'
|
|
steps:
|
|
- name: Post or update the artifact-links comment
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const run = context.payload.workflow_run;
|
|
const { owner, repo } = context.repo;
|
|
|
|
// Resolve the PR. Same-repo PRs are in workflow_run.pull_requests, but
|
|
// fork PRs leave it empty AND their head commit is not on a base-repo
|
|
// branch, so listPullRequestsAssociatedWithCommit misses them too. Match
|
|
// the open PR by its head "owner:branch" instead, which works for forks.
|
|
let prNumber;
|
|
if (run.pull_requests && run.pull_requests.length > 0) {
|
|
prNumber = run.pull_requests[0].number;
|
|
} else {
|
|
let candidates = [];
|
|
const headOwner = run.head_repository && run.head_repository.owner
|
|
? run.head_repository.owner.login
|
|
: null;
|
|
if (headOwner && run.head_branch) {
|
|
const byHead = await github.rest.pulls.list({
|
|
owner, repo, state: 'open',
|
|
head: `${headOwner}:${run.head_branch}`, per_page: 10,
|
|
});
|
|
candidates = byHead.data;
|
|
}
|
|
if (candidates.length === 0) {
|
|
const byCommit = await github.rest.repos.listPullRequestsAssociatedWithCommit({
|
|
owner, repo, commit_sha: run.head_sha,
|
|
});
|
|
candidates = byCommit.data.filter(pr => pr.state === 'open');
|
|
}
|
|
if (candidates.length === 0) {
|
|
core.info('No open PR for this build; nothing to comment.');
|
|
return;
|
|
}
|
|
prNumber = candidates[0].number;
|
|
}
|
|
|
|
// Collect the per-platform artifacts the build produced.
|
|
const artifacts = await github.paginate(
|
|
github.rest.actions.listWorkflowRunArtifacts,
|
|
{ owner, repo, run_id: run.id, per_page: 100 },
|
|
);
|
|
const platforms = [
|
|
{ key: 'win-x64', label: 'Windows (win-x64)' },
|
|
{ key: 'linux-x64', label: 'Linux (linux-x64)' },
|
|
{ key: 'osx-x64', label: 'macOS (osx-x64)' },
|
|
];
|
|
const rows = [];
|
|
for (const platform of platforms) {
|
|
const artifact = artifacts.find(a => a.name.includes(platform.key));
|
|
if (!artifact) {
|
|
continue;
|
|
}
|
|
const url = `https://github.com/${owner}/${repo}/actions/runs/${run.id}/artifacts/${artifact.id}`;
|
|
rows.push(`| ${platform.label} | [\`${artifact.name}\`](${url}) |`);
|
|
}
|
|
if (rows.length === 0) {
|
|
core.info('No platform artifacts on this run; nothing to comment.');
|
|
return;
|
|
}
|
|
|
|
const marker = '<!-- pr-build-links -->';
|
|
const body = [
|
|
marker,
|
|
`### 📦 Build artifacts — \`${run.head_sha.substring(0, 7)}\``,
|
|
'',
|
|
'| Platform | Download |',
|
|
'| --- | --- |',
|
|
...rows,
|
|
'',
|
|
`From [build run #${run.run_number}](${run.html_url}). ` +
|
|
'Downloads require a GitHub login and expire after 90 days.',
|
|
].join('\n');
|
|
|
|
// Upsert one comment so repeated builds refresh it in place.
|
|
const comments = await github.paginate(github.rest.issues.listComments, {
|
|
owner, repo, issue_number: prNumber, 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: prNumber, body });
|
|
}
|