Rerun Workflows #1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Rerun Workflows | |
| on: | |
| issue_comment: | |
| types: [created] | |
| jobs: | |
| rerun: | |
| name: Rerun CI Workflows | |
| # Only run on PR comments (not issue comments) with /rerun command | |
| if: | | |
| github.event.issue.pull_request && | |
| contains(github.event.comment.body, '/rerun') | |
| runs-on: ubuntu-latest | |
| permissions: | |
| actions: write | |
| pull-requests: read | |
| contents: read | |
| steps: | |
| - name: Get PR SHA | |
| id: pr | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const { data: pr } = await github.rest.pulls.get({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: context.issue.number | |
| }); | |
| core.setOutput('sha', pr.head.sha); | |
| core.setOutput('head_ref', pr.head.ref); | |
| console.log(`PR #${context.issue.number} SHA: ${pr.head.sha}`); | |
| console.log(`PR head ref: ${pr.head.ref}`); | |
| - name: Add reaction to comment | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| await github.rest.reactions.createForIssueComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: context.payload.comment.id, | |
| content: 'rocket' | |
| }); | |
| - name: Post start comment | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const comment = context.payload.comment.body; | |
| const rerunMatch = comment.match(/\/rerun\s*(\S+)?/); | |
| const rerunArg = rerunMatch && rerunMatch[1] ? rerunMatch[1] : 'failed'; | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: `🚀 **Workflow rerun started**\n\nMode: \`${rerunArg}\`\nTriggered by: @${context.payload.comment.user.login}\n\n[View Actions](https://github.com/${context.repo.owner}/${context.repo.repo}/actions)` | |
| }); | |
| - name: Rerun failed workflows | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const sha = '${{ steps.pr.outputs.sha }}'; | |
| const headRef = '${{ steps.pr.outputs.head_ref }}'; | |
| // Get all workflow runs for this PR's head SHA | |
| const { data: runs } = await github.rest.actions.listWorkflowRunsForRepo({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| head_sha: sha, | |
| per_page: 100 | |
| }); | |
| console.log(`Found ${runs.total_count} workflow runs for SHA ${sha}`); | |
| if (runs.total_count === 0) { | |
| console.log('No workflow runs found for this PR'); | |
| return; | |
| } | |
| // Parse command for specific workflow filter | |
| // Supports: /rerun, /rerun all, /rerun failed, /rerun <workflow-name> | |
| const comment = context.payload.comment.body; | |
| const rerunMatch = comment.match(/\/rerun\s*(\S+)?/); | |
| const rerunArg = rerunMatch && rerunMatch[1] ? rerunMatch[1].toLowerCase() : 'failed'; | |
| console.log(`Rerun mode: ${rerunArg}`); | |
| let rerunCount = 0; | |
| for (const run of runs.workflow_runs) { | |
| const shouldRerun = | |
| rerunArg === 'all' || | |
| (rerunArg === 'failed' && ['failure', 'cancelled', 'timed_out'].includes(run.conclusion)) || | |
| run.name.toLowerCase().includes(rerunArg); | |
| if (!shouldRerun) { | |
| console.log(`Skipping ${run.name} (status: ${run.status}, conclusion: ${run.conclusion})`); | |
| continue; | |
| } | |
| // Only rerun completed workflows | |
| if (run.status !== 'completed') { | |
| console.log(`Skipping ${run.name} - still ${run.status}`); | |
| continue; | |
| } | |
| try { | |
| console.log(`Rerunning workflow: ${run.name} (ID: ${run.id})`); | |
| // Use rerun-failed-jobs if available and workflow failed, otherwise full rerun | |
| if (['failure', 'cancelled', 'timed_out'].includes(run.conclusion)) { | |
| await github.rest.actions.reRunWorkflowFailedJobs({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| run_id: run.id | |
| }); | |
| } else { | |
| await github.rest.actions.reRunWorkflow({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| run_id: run.id | |
| }); | |
| } | |
| rerunCount++; | |
| } catch (error) { | |
| console.log(`Failed to rerun ${run.name}: ${error.message}`); | |
| } | |
| } | |
| console.log(`Reran ${rerunCount} workflow(s)`); | |
| - name: Post completion comment | |
| if: always() | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const status = '${{ job.status }}'; | |
| const emoji = status === 'success' ? '✅' : '❌'; | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: `${emoji} **Workflow rerun ${status}**\n\n[View Actions](https://github.com/${context.repo.owner}/${context.repo.repo}/actions)` | |
| }); |