Skip to content

Commit 36d7b3d

Browse files
committed
fix: skip orphaned check suites when checking GitHub CI
`checkGitHubCI()` blocks landing with "GitHub CI is still running" whenever any GitHub Actions check suite has a status other than COMPLETED. GitHub occasionally creates check suites that stay stuck in QUEUED with zero check runs and are never dispatched, so they never complete. These orphaned suites block the commit queue indefinitely and force collaborators to land PRs manually. Skip a non-completed suite only when it has no check runs and was created more than 3 hours ago, since a legitimately queued suite gets its runs attached within seconds. Suites with active runs still block as before, and a fresh empty suite (within the window) is not skipped. Adds `createdAt` to the checkSuites GraphQL query to compute suite age. Refs: #1160 Signed-off-by: Naman Trivedi <trivenay@amazon.com>
1 parent c53f184 commit 36d7b3d

4 files changed

Lines changed: 65 additions & 1 deletion

File tree

‎lib/pr_checker.js‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,8 +460,19 @@ export default class PRChecker {
460460
const pendingJobs = [];
461461

462462
// GitHub new Check API
463-
for (const { status, conclusion, checkRuns } of checkSuites.nodes) {
463+
for (const { status, conclusion, checkRuns, createdAt } of checkSuites.nodes) {
464464
if (status !== 'COMPLETED') {
465+
// Skip orphaned check suites that have no runs and are older than
466+
// 3 hours. These are suites that GitHub created but never dispatched,
467+
// and they will never complete. See nodejs/node-core-utils#1160.
468+
const runCount = checkRuns?.nodes?.length ?? 0;
469+
const ageMs = Date.now() - new Date(createdAt).getTime();
470+
const ORPHAN_TIMEOUT_MS = 3 * 60 * 60 * 1000; // 3 hours
471+
if (runCount === 0 && ageMs > ORPHAN_TIMEOUT_MS) {
472+
cli.warn('Ignoring orphaned check suite with no runs ' +
473+
`(status: ${status}, age: ${Math.round(ageMs / 3600000)}h)`);
474+
continue;
475+
}
465476
pendingJobs.push({ status, conclusion });
466477
continue;
467478
}

‎lib/queries/PR.gql‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ query PR($prid: Int!, $owner: String!, $repo: String!) {
3535
# https://api.github.com/apps/github-actions
3636
checkSuites(first: 100, filterBy: { appId: 15368 }) {
3737
nodes {
38+
createdAt,
3839
conclusion,
3940
status,
4041
checkRuns(first: 40) {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
[
2+
{
3+
"commit": {
4+
"committedDate": "2017-10-26T12:10:20Z",
5+
"oid": "9d098ssiskj8dhd39js0sjd0cn2ng4is9n40sj12d",
6+
"messageHeadline": "doc: add api description README",
7+
"author": {
8+
"login": "foo"
9+
},
10+
"checkSuites": {
11+
"nodes": [
12+
{
13+
"status": "COMPLETED",
14+
"conclusion": "SUCCESS",
15+
"createdAt": "2024-01-01T00:00:00Z",
16+
"checkRuns": {
17+
"nodes": [
18+
{
19+
"name": "test-linux",
20+
"status": "COMPLETED",
21+
"conclusion": "SUCCESS",
22+
"detailsUrl": "https://example.com"
23+
}
24+
]
25+
}
26+
},
27+
{
28+
"status": "QUEUED",
29+
"conclusion": null,
30+
"createdAt": "2024-01-01T00:00:00Z",
31+
"checkRuns": {
32+
"nodes": []
33+
}
34+
}
35+
]
36+
}
37+
}
38+
}
39+
]

‎test/unit/pr_checker.test.js‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1803,6 +1803,19 @@ describe('PRChecker', () => {
18031803
cli.assertCalledWith(expectedLogs);
18041804
});
18051805

1806+
it('should skip orphaned check suite with no runs older than 3 hours',
1807+
async() => {
1808+
const cli = new TestCLI();
1809+
1810+
const commits = githubCI['check-suite-orphaned'];
1811+
const data = Object.assign({}, baseData, { commits });
1812+
1813+
const checker = new PRChecker(cli, data, {}, testArgv);
1814+
1815+
const status = await checker.checkCI();
1816+
assert(status);
1817+
});
1818+
18061819
it('should error if commit status failed', async() => {
18071820
const cli = new TestCLI();
18081821

0 commit comments

Comments
 (0)