@@ -3,10 +3,16 @@ name: release-post-comment
33on :
44 # Trigger after release workflow completes (ensures all 4 base workflows finished)
55 # release.yml waits for: wheels, wheels-docker, wstest, main
6+ # NOTE: workflow_run does NOT trigger for fork PRs (GitHub security restriction)
67 workflow_run :
78 workflows : ["release"]
89 types : [completed]
910
11+ # Fallback trigger for fork PRs (workflow_run doesn't fire for these)
12+ # Will poll/wait for release to be ready before posting comment
13+ pull_request_target :
14+ types : [opened, synchronize]
15+
1016 # Manual dispatch for debugging
1117 workflow_dispatch :
1218 inputs :
@@ -35,9 +41,102 @@ jobs:
3541 # IMPORTANT: we still need .cicd as a Git submodule in the using repo though!
3642 # because e.g. identifiers.yml wants to access scripts/sanitize.sh !
3743
44+ wait-for-release :
45+ name : Wait for release (pull_request_target only)
46+ needs : identifiers
47+ # Only run when triggered by pull_request_target (fork PRs)
48+ if : github.event_name == 'pull_request_target'
49+ runs-on : ubuntu-latest
50+
51+ steps :
52+ - name : Wait for release workflow to complete
53+ uses : actions/github-script@v7
54+ with :
55+ script : |
56+ const maxWaitMinutes = 60; // Maximum wait time
57+ const pollIntervalSeconds = 30; // Check every 30 seconds
58+ const maxAttempts = (maxWaitMinutes * 60) / pollIntervalSeconds;
59+
60+ const commitSha = context.payload.pull_request.head.sha;
61+ console.log(`Waiting for release workflow to complete for commit: ${commitSha}`);
62+ console.log(`Max wait: ${maxWaitMinutes} minutes, polling every ${pollIntervalSeconds} seconds`);
63+
64+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
65+ console.log(`\nAttempt ${attempt}/${maxAttempts} - Checking for release workflow...`);
66+
67+ // Check if release workflow has completed for this commit
68+ const { data: runs } = await github.rest.actions.listWorkflowRunsForRepo({
69+ owner: context.repo.owner,
70+ repo: context.repo.repo,
71+ workflow_id: 'release.yml',
72+ head_sha: commitSha,
73+ per_page: 10
74+ });
75+
76+ const releaseRun = runs.workflow_runs.find(run =>
77+ run.head_sha === commitSha &&
78+ run.status === 'completed'
79+ );
80+
81+ if (releaseRun) {
82+ console.log(`✅ Release workflow completed with status: ${releaseRun.conclusion}`);
83+ console.log(` Run URL: ${releaseRun.html_url}`);
84+
85+ if (releaseRun.conclusion === 'success') {
86+ console.log('Release workflow succeeded - proceeding with comment posting');
87+ return;
88+ } else {
89+ core.setFailed(`Release workflow completed with conclusion: ${releaseRun.conclusion}`);
90+ return;
91+ }
92+ }
93+
94+ // Check if any base workflows are still running
95+ const baseWorkflows = ['main', 'wheels', 'wheels-docker', 'wstest'];
96+ const runningWorkflows = [];
97+
98+ for (const workflowName of baseWorkflows) {
99+ const { data: workflowRuns } = await github.rest.actions.listWorkflowRunsForRepo({
100+ owner: context.repo.owner,
101+ repo: context.repo.repo,
102+ workflow_id: `${workflowName}.yml`,
103+ head_sha: commitSha,
104+ per_page: 5
105+ });
106+
107+ const workflowRun = workflowRuns.workflow_runs.find(run => run.head_sha === commitSha);
108+ if (workflowRun && workflowRun.status !== 'completed') {
109+ runningWorkflows.push(`${workflowName} (${workflowRun.status})`);
110+ }
111+ }
112+
113+ if (runningWorkflows.length > 0) {
114+ console.log(`⏳ Base workflows still running: ${runningWorkflows.join(', ')}`);
115+ } else {
116+ console.log('⏳ All base workflows completed, waiting for release workflow...');
117+ }
118+
119+ if (attempt < maxAttempts) {
120+ console.log(`Sleeping ${pollIntervalSeconds} seconds before next check...`);
121+ await new Promise(resolve => setTimeout(resolve, pollIntervalSeconds * 1000));
122+ }
123+ }
124+
125+ core.setFailed(`Timeout: Release workflow did not complete within ${maxWaitMinutes} minutes`);
126+
127+
38128 check-release-exists :
39129 name : Check if release created (Early Exit Pattern)
40- needs : identifiers
130+ needs : [identifiers, wait-for-release]
131+ # For pull_request_target: wait-for-release must succeed
132+ # For workflow_run: proceed immediately (release already completed)
133+ # For workflow_dispatch: proceed immediately (manual trigger)
134+ if : |
135+ always() &&
136+ needs.identifiers.result == 'success' &&
137+ (github.event_name == 'workflow_run' ||
138+ github.event_name == 'workflow_dispatch' ||
139+ (github.event_name == 'pull_request_target' && needs.wait-for-release.result == 'success'))
41140 runs-on : ubuntu-latest
42141 outputs :
43142 should_process : ${{ steps.check.outputs.should_process }}
@@ -266,8 +365,12 @@ jobs:
266365 uses : actions/github-script@v7
267366 with :
268367 script : |
269- const commitSha = context.payload.workflow_run.head_sha;
368+ // Handle both workflow_run and pull_request_target triggers
369+ const commitSha = context.payload.workflow_run?.head_sha ||
370+ context.payload.pull_request?.head.sha ||
371+ context.sha;
270372 console.log(`Finding wstest workflow for commit: ${commitSha}`);
373+ console.log(`Triggered by: ${context.eventName}`);
271374
272375 const { data: runs } = await github.rest.actions.listWorkflowRunsForRepo({
273376 owner: context.repo.owner,
@@ -367,7 +470,13 @@ jobs:
367470 fi
368471 fi
369472
370- WORKFLOW_RUN_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${{ github.event.workflow_run.id }}"
473+ # Construct workflow run URL (handle both workflow_run and pull_request_target triggers)
474+ if [ "${{ github.event_name }}" = "workflow_run" ]; then
475+ WORKFLOW_RUN_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${{ github.event.workflow_run.id }}"
476+ else
477+ # For pull_request_target or workflow_dispatch, link to current run
478+ WORKFLOW_RUN_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${{ github.run_id }}"
479+ fi
371480
372481 # Read release notes (already fetched)
373482 RELEASE_NOTES=$(cat release-notes.md)
@@ -444,8 +553,12 @@ jobs:
444553 uses : actions/github-script@v7
445554 with :
446555 script : |
447- const commitSha = context.payload.workflow_run.head_sha;
556+ // Handle both workflow_run and pull_request_target triggers
557+ const commitSha = context.payload.workflow_run?.head_sha ||
558+ context.payload.pull_request?.head.sha ||
559+ context.sha;
448560 console.log(`Finding wstest workflow for commit: ${commitSha}`);
561+ console.log(`Triggered by: ${context.eventName}`);
449562
450563 const { data: runs } = await github.rest.actions.listWorkflowRunsForRepo({
451564 owner: context.repo.owner,
0 commit comments