|
1 | 1 | const core = require('@actions/core'); |
2 | 2 | const github = require('@actions/github'); |
3 | | -const stringify = require('json-stringify-safe'); |
| 3 | +const { DateTime } = require('luxon'); |
4 | 4 |
|
5 | | -async function run() { |
| 5 | +async function runAction() { |
6 | 6 | // Attempt to load credentials from the GitHub OIDC provider. |
7 | 7 | const githubSecretAccessToken = core.getInput('github_token'); |
8 | 8 | if (!githubSecretAccessToken || githubSecretAccessToken === '{{ secrets.GITHUB_TOKEN }}') { |
| 9 | + // GitHub core library has a critical failure if we don't escape the $, seems like a malicious attack vector they aren't handling correctly |
| 10 | + // eslint-disable-next-line no-useless-escape |
9 | 11 | core.setFailed("Missing use with configuration in the github action, please add to the github workflow: 'github_token: ${{ secrets.GITHUB_TOKEN }}'"); |
10 | 12 | core.getInput('github_token', { required: true }); |
11 | 13 | throw Error('InvalidInput'); |
12 | 14 | } |
13 | 15 |
|
14 | 16 | // https://docs.github.com/en/actions/learn-github-actions/contexts#example-contents-of-the-github-contex |
15 | | - const { repository, repository_owner: owner, ref_name: currentRef, ref_type: triggerType } = github.context; |
16 | | - if (!triggerType) { |
17 | | - core.info(stringify(github)); |
18 | | - core.setFailed('No trigger type set'); |
19 | | - throw Error('InvalidInput'); |
20 | | - } |
21 | | - if (triggerType !== 'branch') { |
22 | | - core.info(`Skipping check because trigger type is not branch. Trigger Type: ${triggerType}, Ref: ${currentRef}`); |
23 | | - return; |
24 | | - } |
| 17 | + const currentRef = github.context.payload.ref.replace(/^refs\/heads\//, ''); |
| 18 | + const workflowTarget = github.context.workflow; |
| 19 | + core.info(`Branch Ref: ${currentRef}, Workflow: ${workflowTarget}`); |
| 20 | + const [owner, repo] = github.context.payload.repository.full_name.split('/'); |
25 | 21 |
|
26 | 22 | const octokit = github.getOctokit(githubSecretAccessToken); |
27 | | - const branches = await octokit.rest.repos.listBranches({ |
28 | | - owner: owner, |
29 | | - repo: repository |
| 23 | + |
| 24 | + const openPullRequestsResponse = await octokit.rest.pulls.list({ owner, repo, state: 'open', base: currentRef, per_page: 100 }); |
| 25 | + core.info(`Relevant open pull requests: [${openPullRequestsResponse.data.map(pr => pr.number).join(', ')}]`); |
| 26 | + |
| 27 | + const prMap = openPullRequestsResponse.data.reduce((acc, pr) => { acc[pr.number] = true; return acc; }, {}); |
| 28 | + |
| 29 | + const workflowRuns = await octokit.rest.actions.listWorkflowRuns({ |
| 30 | + owner, repo, workflow_id: workflowTarget, event: 'pull_request', created: `>= ${DateTime.utc().minus({ month: 1 }).toISODate()}`, per_page: 100 |
30 | 31 | }); |
31 | | - // https://docs.github.com/en/rest/actions/workflows?apiVersion=2022-11-28#create-a-workflow-dispatch-event |
32 | | - const filteredBranches = branches.data.filter(branch => branch.name !== currentRef); |
33 | | - await Promise.all(filteredBranches.map(async branch => { |
| 32 | + |
| 33 | + const workflowRunsForAffectedPrs = workflowRuns.data.workflow_runs.filter(run => run.pull_requests?.some(pr => prMap[pr.number])); |
| 34 | + await Promise.all(workflowRunsForAffectedPrs.map(async run => { |
34 | 35 | try { |
35 | | - await octokit.rest.repos.createDispatchEvent({ |
36 | | - owner: owner, |
37 | | - repo: repository, |
38 | | - workflow_id: github.workflow, |
39 | | - ref: branch |
| 36 | + await core.info(`Attempting to rerun: ${run.id}`); |
| 37 | + await octokit.rest.actions.reRunWorkflow({ |
| 38 | + owner, repo, run_id: run.id |
40 | 39 | }); |
41 | 40 | } catch (error) { |
42 | | - core.error(`Failed to automatically trigger branch ${branch}: ${error.code} - ${error.message}`); |
| 41 | + core.error(`Failed to automatically retrigger pull request: ${run.pull_requests?.map(pr => pr.number).join(',')}: ${error.status} - ${error.message}`); |
43 | 42 | } |
44 | 43 | })); |
45 | 44 | } |
46 | 45 |
|
47 | | -exports.run = run; |
| 46 | +exports.run = runAction; |
48 | 47 |
|
49 | 48 | if (require.main === module) { |
50 | | - run(); |
| 49 | + runAction(); |
51 | 50 | } |
0 commit comments