/
index.ts
100 lines (88 loc) · 3.24 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import * as core from '@actions/core';
import * as github from '@actions/github';
if (!github) {
throw new Error('Module not found: github');
}
if (!core) {
throw new Error('Module not found: core');
}
async function main() {
const { eventName, sha, ref, repo: { owner, repo }, payload } = github.context;
const { GITHUB_RUN_ID } = process.env;
let branch = ref.slice(11);
let headSha = sha;
if (payload.pull_request) {
branch = payload.pull_request.head.ref;
headSha = payload.pull_request.head.sha;
}
console.log({ eventName, sha, headSha, branch, owner, repo, GITHUB_RUN_ID });
const token = core.getInput('access_token', { required: true });
const workflow_id = core.getInput('workflow_id', { required: false });
const all_but_latest = core.getInput('all_but_latest', { required: false });
console.log(`Found token: ${token ? 'yes' : 'no'}`);
const workflow_ids: number[] = [];
const octokit = github.getOctokit(token);
const { data: current_run } = await octokit.actions.getWorkflowRun({
owner,
repo,
run_id: Number(GITHUB_RUN_ID)
});
if (workflow_id) {
// The user provided one or more workflow id
workflow_id.replace(/\s/g, '')
.split(',')
.map(s => Number(s))
.forEach(n => workflow_ids.push(n));
} else {
// The user did not provide workflow id so derive from current run
workflow_ids.push(current_run.workflow_id);
}
console.log(`Found workflow_id: ${JSON.stringify(workflow_ids)}`);
await Promise.all(workflow_ids.map(async (workflow_id) => {
try {
const { data } = await octokit.actions.listWorkflowRuns({
owner,
repo,
workflow_id,
branch
});
console.log(`Found ${data.total_count} runs total.`);
let cancel_before;
if (all_but_latest) {
cancel_before = new Date(data.workflow_runs.reduce((a, b) => Math.min(a.created_at, b.created_at);
} else {
cancel_before = new Date(current_run.created_at);
}
const runningWorkflows = data.workflow_runs.filter(
run => run.head_branch === branch && run.head_sha !== headSha && run.status !== 'completed' &&
run != current_run &&
new Date(run.created_at) < cancel_before
);
console.log(`Found ${runningWorkflows.length} runs to cancel.`);
for (const {id, head_sha, status} of runningWorkflows) {
console.log('Cancelling another run: ', {id, head_sha, status});
const res = await octokit.actions.cancelWorkflowRun({
owner,
repo,
run_id: id
});
console.log(`Cancel run ${id} responded with status ${res.status}`);
}
if (all_but_latest && new Date(current_run.created_at) < cancel_before) {
// FIXME actions/core doesn't support cancelling, so we need to do it through the API
const res = await octokit.actions.cancelWorkflowRun({
owner,
repo,
run_id: id
});
console.log(`Cancel run ${id} responded with status ${res.status}`);
}
} catch (e) {
const msg = e.message || e;
console.log(`Error while cancelling workflow_id ${workflow_id}: ${msg}`);
}
}));
}
main()
.then(() => core.info('Cancel Complete.'))
.catch(e => core.setFailed(e.message));