Skip to content

Commit 675fd6e

Browse files
committed
refactor(pr-job-rerun): run failed, all or a job
1 parent 7c00367 commit 675fd6e

2 files changed

Lines changed: 78 additions & 58 deletions

File tree

pr/checks-rerun/action.yml

Lines changed: 0 additions & 58 deletions
This file was deleted.

pr/job-rerun/action.yml

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
name: Rerun Job
2+
description: Reruns job of the latest completed run of a workflow for the current PR SHA
3+
4+
inputs:
5+
workflow-id:
6+
description: Workflow filename to rerun
7+
required: false
8+
default: .github/workflows/pull-request.yml
9+
token:
10+
description: 'GitHub token or PAT with actions:write permission'
11+
required: false
12+
default: ${{ github.token }}
13+
job-name:
14+
description: 'Name of the job to rerun. If not specified, reruns all failed jobs or the entire workflow run based on rerun-failed input'
15+
required: false
16+
rerun-failed:
17+
description: 'If true (default), reruns only failed jobs. If false, triggers a clean run of all jobs'
18+
required: false
19+
default: 'true'
20+
21+
runs:
22+
using: composite
23+
steps:
24+
- name: Rerun job(s)
25+
uses: actions/github-script@v7
26+
with:
27+
github-token: ${{ inputs.token }}
28+
script: |
29+
const owner = context.repo.owner;
30+
const repo = context.repo.repo;
31+
const headSha = context.payload.pull_request.head.sha;
32+
33+
const { data: { workflow_runs } } = await github.rest.actions.listWorkflowRuns({
34+
owner, repo,
35+
workflow_id: '${{ inputs.workflow-id }}',
36+
event: 'pull_request',
37+
head_sha: headSha,
38+
per_page: 20,
39+
});
40+
41+
// Skip if a run is already active to avoid concurrency deadlock
42+
const activeRun = workflow_runs.find(r =>
43+
['in_progress', 'queued', 'waiting', 'pending', 'requested'].includes(r.status)
44+
);
45+
if (activeRun) {
46+
core.info(`Workflow run ${activeRun.id} is already ${activeRun.status}, skipping rerun.`);
47+
return;
48+
}
49+
50+
const completedRun = workflow_runs.find(r => r.status === 'completed');
51+
if (!completedRun) {
52+
core.warning('No workflow runs found for the current HEAD SHA.');
53+
return;
54+
}
55+
56+
const jobName = '${{ inputs.job-name }}';
57+
if (jobName) {
58+
const { data: { jobs } } = await github.rest.actions.listJobsForWorkflowRun({
59+
owner, repo, run_id: completedRun.id, filter: 'latest', per_page: 100,
60+
});
61+
const job = jobs.find(j => j.name === jobName);
62+
if (!job) {
63+
core.setFailed(`Job "${jobName}" not found in run ${completedRun.id}. Available: ${jobs.map(j => j.name).join(', ')}`);
64+
return;
65+
}
66+
core.info(`Rerunning job "${job.name}" (id: ${job.id}) from run ${completedRun.id}`);
67+
await github.rest.actions.reRunJobForWorkflowRun({ owner, repo, job_id: job.id });
68+
return;
69+
}
70+
71+
const rerunFailed = '${{ inputs.rerun-failed }}' === 'true';
72+
if (rerunFailed) {
73+
core.info(`Rerunning failed jobs for run ${completedRun.id} (conclusion: ${completedRun.conclusion})`);
74+
await github.rest.actions.reRunWorkflowFailedJobs({ owner, repo, run_id: completedRun.id });
75+
} else {
76+
core.info(`Rerunning all jobs for run ${completedRun.id} (conclusion: ${completedRun.conclusion})`);
77+
await github.rest.actions.reRunWorkflow({ owner, repo, run_id: completedRun.id });
78+
}

0 commit comments

Comments
 (0)