Skip to content

Commit 1f01010

Browse files
authored
Cleanup all_but_latest (#67)
1 parent 1adde81 commit 1f01010

File tree

3 files changed

+38
-38
lines changed

3 files changed

+38
-38
lines changed

README.md

+4-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This includes runs with a [status](https://docs.github.com/en/rest/reference/che
66

77
## How does it work?
88

9-
When you `git push`, this GitHub Action will capture the current Branch and SHA. It will query GitHub's API to find previous workflow runs that match the Branch but do not match the SHA. These in-progress runs will be canceled leaving only this run.
9+
When you `git push`, this GitHub Action will capture the current Branch and SHA. It will query GitHub's API to find previous workflow runs that match the Branch but do not match the SHA. These in-progress runs will be canceled leaving only this run, or the [latest run](#advanced-all-but-latest).
1010

1111
Read more about the [Workflow Runs API](https://docs.github.com/en/rest/reference/actions#workflow-runs).
1212

@@ -100,10 +100,11 @@ jobs:
100100
workflow_id: 479426
101101
```
102102

103-
## Advanced: Cancel more recent workflows
103+
## Advanced: All But Latest
104104

105105
Because this action can only cancel workflows if it is actually being run, it only helps if the pipeline isn't saturated and there are still runners available to schedule the workflow.
106-
By default, this action does not cancel any workflows older than itself. The optional flag ``all_but_latest`` switches to a mode where the action also cancels itself and all later-scheduled workflows but the last one.
106+
107+
By default, this action does not cancel any workflows created after itself. The `all_but_latest` flags allows the action to cancel itself and all later-scheduled workflows, leaving only the latest.
107108

108109
```yml
109110
name: Cancel
@@ -120,8 +121,6 @@ jobs:
120121
access_token: ${{ github.token }}
121122
```
122123

123-
At the time of writing `0.8.0` is the latest release but you can select any [release](https://github.com/styfle/cancel-workflow-action/releases).
124-
125124
## Contributing
126125

127126
- Clone this repo

dist/index.js

+16-7
Original file line numberDiff line numberDiff line change
@@ -5864,6 +5864,7 @@ async function main() {
58645864
const token = core.getInput('access_token', { required: true });
58655865
const workflow_id = core.getInput('workflow_id', { required: false });
58665866
const ignore_sha = core.getInput('ignore_sha', { required: false }) === 'true';
5867+
const all_but_latest = core.getInput('all_but_latest', { required: false });
58675868
console.log(`Found token: ${token ? 'yes' : 'no'}`);
58685869
const workflow_ids = [];
58695870
const octokit = github.getOctokit(token);
@@ -5883,19 +5884,27 @@ async function main() {
58835884
console.log(`Found workflow_id: ${JSON.stringify(workflow_ids)}`);
58845885
await Promise.all(workflow_ids.map(async (workflow_id) => {
58855886
try {
5886-
const { data } = await octokit.actions.listWorkflowRuns({
5887+
const { data: { total_count, workflow_runs } } = await octokit.actions.listWorkflowRuns({
5888+
per_page: 100,
58875889
owner,
58885890
repo,
58895891
workflow_id,
58905892
branch,
58915893
});
5892-
const branchWorkflows = data.workflow_runs.filter(run => run.head_branch === branch);
5893-
console.log(`Found ${branchWorkflows.length} runs for workflow ${workflow_id} on branch ${branch}`);
5894-
console.log(branchWorkflows.map(run => `- ${run.html_url}`).join('\n'));
5895-
const runningWorkflows = branchWorkflows.filter(run => (ignore_sha || run.head_sha !== headSha) &&
5894+
console.log(`Found ${total_count} runs total.`);
5895+
let cancelBefore = new Date(current_run.created_at);
5896+
if (all_but_latest) {
5897+
const n = workflow_runs.map(run => new Date(run.created_at).getTime()).reduce((a, b) => Math.max(a, b), cancelBefore.getTime());
5898+
cancelBefore = new Date(n);
5899+
}
5900+
const runningWorkflows = workflow_runs.filter(run => run.id !== current_run.id &&
5901+
(ignore_sha || run.head_sha !== headSha) &&
58965902
run.status !== 'completed' &&
5897-
new Date(run.created_at) < new Date(current_run.created_at));
5898-
console.log(`with ${runningWorkflows.length} runs to cancel.`);
5903+
new Date(run.created_at) < cancelBefore);
5904+
if (all_but_latest && new Date(current_run.created_at) < cancelBefore) {
5905+
runningWorkflows.push(current_run);
5906+
}
5907+
console.log(`Found ${runningWorkflows.length} runs to cancel.`);
58995908
for (const { id, head_sha, status, html_url } of runningWorkflows) {
59005909
console.log('Canceling run: ', { id, head_sha, status, html_url });
59015910
const res = await octokit.actions.cancelWorkflowRun({

src/index.ts

+18-26
Original file line numberDiff line numberDiff line change
@@ -47,34 +47,36 @@ async function main() {
4747
// The user did not provide workflow id so derive from current run
4848
workflow_ids.push(String(current_run.workflow_id));
4949
}
50-
5150
console.log(`Found workflow_id: ${JSON.stringify(workflow_ids)}`);
52-
5351
await Promise.all(workflow_ids.map(async (workflow_id) => {
5452
try {
55-
const { data } = await octokit.actions.listWorkflowRuns({
53+
const { data: { total_count, workflow_runs } } = await octokit.actions.listWorkflowRuns({
54+
per_page: 100,
5655
owner,
5756
repo,
5857
// @ts-ignore
5958
workflow_id,
6059
branch,
6160
});
62-
console.log(`Found ${data.total_count} runs total.`);
63-
64-
let cancel_before;
61+
console.log(`Found ${total_count} runs total.`);
62+
let cancelBefore = new Date(current_run.created_at);
6563
if (all_but_latest) {
66-
cancel_before = new Date(data.workflow_runs.reduce((a, b) => Math.max(a.created_at, b.created_at)));
67-
} else {
68-
cancel_before = new Date(current_run.created_at);
64+
const n = workflow_runs.map(run => new Date(run.created_at).getTime()).reduce((a, b) => Math.max(a, b), cancelBefore.getTime());
65+
cancelBefore = new Date(n);
6966
}
70-
71-
const runningWorkflows = data.workflow_runs.filter(
72-
run => run.head_branch === branch && (ignore_sha || run.head_sha !== headSha) && run.status !== 'completed' &&
73-
run != current_run &&
74-
new Date(run.created_at) < cancel_before
67+
const runningWorkflows = workflow_runs.filter(run =>
68+
run.id !== current_run.id &&
69+
(ignore_sha || run.head_sha !== headSha) &&
70+
run.status !== 'completed' &&
71+
new Date(run.created_at) < cancelBefore
7572
);
73+
if (all_but_latest && new Date(current_run.created_at) < cancelBefore) {
74+
// Make sure we cancel this run itself if it's out-of-date.
75+
// We must cancel this run last so we can cancel the others first.
76+
runningWorkflows.push(current_run);
77+
}
7678
console.log(`Found ${runningWorkflows.length} runs to cancel.`);
77-
for (const {id, head_sha, status} of runningWorkflows) {
79+
for (const {id, head_sha, status, html_url} of runningWorkflows) {
7880
console.log('Canceling run: ', {id, head_sha, status, html_url});
7981
const res = await octokit.actions.cancelWorkflowRun({
8082
owner,
@@ -83,17 +85,7 @@ async function main() {
8385
});
8486
console.log(`Cancel run ${id} responded with status ${res.status}`);
8587
}
86-
// Make sure we cancel this run itself if it's out-of-date.
87-
// We postponed canceling this run because otherwise we couldn't cancel the rest.
88-
if (all_but_latest && new Date(current_run.created_at) < cancel_before) {
89-
const id = current_run.id;
90-
const res = await octokit.actions.cancelWorkflowRun({
91-
owner,
92-
repo,
93-
run_id: id
94-
});
95-
console.log(`Cancel run ${id} responded with status ${res.status}`);
96-
}
88+
9789
} catch (e) {
9890
const msg = e.message || e;
9991
console.log(`Error while canceling workflow_id ${workflow_id}: ${msg}`);

0 commit comments

Comments
 (0)