Skip to content

Commit ee83263

Browse files
committed
fix: exit early when no active runs found + plenty of debugging
closes #1
1 parent 4978a78 commit ee83263

4 files changed

Lines changed: 72 additions & 29 deletions

File tree

action/lib/deduplicate.js

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,46 @@
11
/* eslint-disable camelcase */
22

3+
// node modules
4+
import { inspect } from 'util'
5+
6+
// packages
37
import core from '@actions/core'
48
import github from '@actions/github'
59

6-
export default async function (octokit) {
7-
// extract sha
8-
const { sha, runId: run_id } = github.context
9-
10-
// get workflow id from run id
11-
const { data: { workflow_id } } = await octokit.request('GET /repos/{owner}/{repo}/actions/runs/{run_id}', {
10+
export default async function ({ octokit, workflow_id, run_id, sha }) {
11+
// get current run of this workflow
12+
const { data: { workflow_runs } } = await octokit.request('GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs', {
1213
...github.context.repo,
13-
run_id
14+
workflow_id
1415
})
1516

16-
// get current run of this workflow
17-
const { data: { workflow_runs } } = await octokit.request('GET /repos/{owner}/{repo}/actions/runs', {
18-
...github.context.repo
19-
})
17+
core.debug(`found ${workflow_runs.length} runs of workflow ${workflow_id}`)
18+
core.debug(inspect(workflow_runs))
2019

21-
// find any instances of the same workflow
20+
// filter and sort
2221
const cancellable = workflow_runs
2322
// filter to relevant runs
24-
.filter(run => ['in_progress', 'queued'].includes(run.status) && run.workflow_id === workflow_id && run.head_sha === sha)
23+
.filter(run => ['in_progress', 'queued'].includes(run.status))
24+
// filter to only runs for the same commit
25+
.filter(run => run.head_sha === sha)
26+
// exclude this one
27+
.filter(run => run.id !== run_id)
2528
// pick relevant properties
2629
.map(run => ({ id: run.id, name: run.name, created_at: run.created_at }))
2730
// sort
2831
.sort((a, b) => new Date(b.created_at) - new Date(a.created_at))
2932

30-
// remove last one
31-
cancellable.pop()
33+
core.debug(`found ${cancellable.length} cancellable runs of workflow ${workflow_id}`)
34+
core.debug(inspect(cancellable))
35+
36+
// exclude last one (i.e. the first running instance)
37+
const prime = cancellable.pop()
38+
39+
core.debug(`determined ${prime.id} to be the prime run of this workflow`)
40+
core.debug(inspect(prime))
3241

3342
for (const run of cancellable) {
34-
core.info(`${run.id}: ${run.name} => cancel`)
43+
core.info(`${run.id}: ${run.name} => canceling`)
3544

3645
await octokit.request('POST /repos/{owner}/{repo}/actions/runs/{run_id}/cancel', {
3746
...github.context.repo,

action/lib/index.js

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
/* eslint-disable camelcase */
2+
13
// packages
24
import core from '@actions/core'
35
import github from '@actions/github'
@@ -15,13 +17,34 @@ export default async function ({ token, delay, timeout }) {
1517
// init octokit
1618
const octokit = github.getOctokit(token)
1719

18-
await deduplicate(octokit)
20+
// extract sha
21+
const { sha, ref, runId: run_id } = github.context
22+
23+
core.debug(`sha: ${sha}`)
24+
core.debug(`run.id: ${run_id}`)
25+
26+
// get workflow id from run id
27+
const { data: { workflow_id } } = await octokit.request('GET /repos/{owner}/{repo}/actions/runs/{run_id}', {
28+
...github.context.repo,
29+
run_id
30+
})
31+
32+
core.debug(`workflow_id: ${workflow_id}`)
1933

20-
const dependencies = await workflows(octokit)
34+
// don't run this workflow twice for the same commit
35+
await deduplicate({ octokit, workflow_id, run_id, sha })
36+
37+
// find all the dependencies
38+
const dependencies = await workflows({ octokit, ref, workflow_id })
2139

2240
// check runs
2341
let result = await runs(octokit, dependencies)
2442

43+
if (result.length === 0) {
44+
core.info('no runs found for this workflow\'s dependencies')
45+
process.exit(1)
46+
}
47+
2548
while (result.find(run => run.conclusion !== 'success')) {
2649
// exit early
2750
const failed = result.find(run => run.conclusion === 'failure')

action/lib/runs.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
// node modules
2+
import { inspect } from 'util'
3+
4+
// packages
5+
import core from '@actions/core'
16
import github from '@actions/github'
27

38
export default async function (octokit, dependencies) {
@@ -8,9 +13,14 @@ export default async function (octokit, dependencies) {
813
...github.context.repo
914
})
1015

11-
return workflow_runs
16+
const runs = workflow_runs
1217
// filter to relevant runs
1318
.filter(run => dependencies.includes(run.name) && run.head_sha === sha)
1419
// pick properties
1520
.map(run => ({ id: run.id, name: run.name, conclusion: run.conclusion }))
21+
22+
core.debug(`found ${runs.length} workflow runs of ${inspect(dependencies)}`)
23+
core.debug(inspect(runs))
24+
25+
return runs
1626
}

action/lib/workflows.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,31 @@
1+
/* eslint-disable camelcase */
2+
3+
// packages
14
import yaml from 'yaml'
25
import github from '@actions/github'
6+
import core from '@actions/core'
37

4-
export default async function (octokit) {
5-
// extract sha
6-
const { ref, runId: run_id } = github.context // eslint-disable-line camelcase
7-
8-
// get workflow id from run id
9-
const { data: { workflow_id } } = await octokit.request('GET /repos/{owner}/{repo}/actions/runs/{run_id}', { // eslint-disable-line camelcase
10-
...github.context.repo,
11-
run_id
12-
})
13-
8+
export default async function ({ octokit, ref, workflow_id }) {
149
// get the file name from the workflow
1510
const { data: { path } } = await octokit.request('GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}', {
1611
...github.context.repo,
1712
workflow_id
1813
})
1914

15+
core.debug(`workflow.path: ${path}`)
16+
2017
// get the workflow content
2118
const { data: { content } } = await octokit.request('GET /repos/{owner}/{repo}/contents/{path}', {
2219
...github.context.repo,
2320
path,
2421
ref
2522
})
2623

24+
core.debug(`workflow content: ${content.length} bytes`)
25+
2726
const { on: { workflow_run: { workflows } } } = yaml.parse(Buffer.from(content, 'base64').toString())
2827

28+
core.debug(`workflow dependencies: ${workflows}`)
29+
2930
return workflows
3031
}

0 commit comments

Comments
 (0)