Skip to content

fix: support list detail of failed GitHub CI #960

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 75 additions & 6 deletions lib/pr_checker.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,8 +359,13 @@ export default class PRChecker {
return false;
}

let hasFailures = false;
const failedJobs = [];
const cancelledJobs = [];
const pendingJobs = [];

// GitHub new Check API
for (const { status, conclusion, app } of checkSuites.nodes) {
for (const { status, conclusion, app, checkRuns } of checkSuites.nodes) {
if (app.slug !== 'github-actions') {
// Ignore all non-github check suites, such as Dependabot and Codecov.
// They are expected to show up on PRs whose head branch is not on a
Expand All @@ -369,16 +374,80 @@ export default class PRChecker {
}

if (status !== 'COMPLETED') {
cli.error('GitHub CI is still running');
return false;
pendingJobs.push({ app: app.slug, status, conclusion });
continue;
}

if (!GITHUB_SUCCESS_CONCLUSIONS.includes(conclusion)) {
cli.error('Last GitHub CI failed');
return false;
hasFailures = true;

// If we have detailed checkRuns, show specific failing jobs
if (checkRuns && checkRuns.nodes && checkRuns.nodes.length > 0) {
for (const checkRun of checkRuns.nodes) {
if (checkRun.status === 'COMPLETED' &&
!GITHUB_SUCCESS_CONCLUSIONS.includes(checkRun.conclusion)) {
if (checkRun.conclusion === 'CANCELLED') {
cancelledJobs.push({
name: checkRun.name,
conclusion: checkRun.conclusion,
url: checkRun.detailsUrl
});
} else {
failedJobs.push({
name: checkRun.name,
conclusion: checkRun.conclusion,
url: checkRun.detailsUrl
});
}
}
}
} else {
// Fallback to check suite level information if no checkRuns
if (conclusion === 'CANCELLED') {
cancelledJobs.push({
name: app.slug,
conclusion,
url: null
});
} else {
failedJobs.push({
name: app.slug,
conclusion,
url: null
});
}
}
}
}

// Report pending jobs
if (pendingJobs.length > 0) {
cli.error('GitHub CI is still running');
return false;
}

// Report failed jobs
if (failedJobs.length > 0) {
cli.error(`${failedJobs.length} GitHub CI job(s) failed:`);
for (const job of failedJobs) {
const urlInfo = job.url ? ` (${job.url})` : '';
cli.error(` - ${job.name}: ${job.conclusion}${urlInfo}`);
}
}

// Report cancelled jobs
if (cancelledJobs.length > 0) {
cli.error(`${cancelledJobs.length} GitHub CI job(s) cancelled:`);
for (const job of cancelledJobs) {
const urlInfo = job.url ? ` (${job.url})` : '';
cli.error(` - ${job.name}: ${job.conclusion}${urlInfo}`);
}
}

if (hasFailures) {
return false;
}

// GitHub old commit status API
if (commit.status) {
const { state } = commit.status;
Expand All @@ -388,7 +457,7 @@ export default class PRChecker {
}

if (!['SUCCESS', 'EXPECTED'].includes(state)) {
cli.error('Last GitHub CI failed');
cli.error(`GitHub CI failed with status: ${state}`);
return false;
}
}
Expand Down
10 changes: 9 additions & 1 deletion lib/queries/PRCommits.gql
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,15 @@ query Commits($prid: Int!, $owner: String!, $repo: String!, $after: String) {
slug
}
conclusion,
status
status,
checkRuns(first: 40) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

github doesn't support 100,000 nodes query so I have to reduce to 40

nodes {
name
status
conclusion
detailsUrl
}
}
}
}
status {
Expand Down
37 changes: 37 additions & 0 deletions test/fixtures/github-ci/check-suite-cancelled.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[
{
"commit": {
"committedDate": "2017-10-26T12:10:20Z",
"oid": "9d098ssiskj8dhd39js0sjd0cn2ng4is9n40sj12d",
"messageHeadline": "doc: add api description README",
"author": {
"login": "foo"
},
"checkSuites": {
"nodes": [
{
"app": { "slug": "github-actions" },
"status": "COMPLETED",
"conclusion": "CANCELLED",
"checkRuns": {
"nodes": [
{
"name": "test-linux",
"status": "COMPLETED",
"conclusion": "CANCELLED",
"detailsUrl": "https://github.com/nodejs/node/runs/12345"
},
{
"name": "lint",
"status": "COMPLETED",
"conclusion": "SUCCESS",
"detailsUrl": "https://github.com/nodejs/node/runs/12346"
}
]
}
}
]
}
}
}
]
18 changes: 17 additions & 1 deletion test/fixtures/github-ci/check-suite-failure.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,23 @@
{
"app": { "slug": "github-actions" },
"status": "COMPLETED",
"conclusion": "FAILURE"
"conclusion": "FAILURE",
"checkRuns": {
"nodes": [
{
"name": "test-linux",
"status": "COMPLETED",
"conclusion": "FAILURE",
"detailsUrl": "https://github.com/nodejs/node/runs/12345"
},
{
"name": "test-macos",
"status": "COMPLETED",
"conclusion": "SUCCESS",
"detailsUrl": "https://github.com/nodejs/node/runs/12346"
}
]
}
}
]
}
Expand Down
16 changes: 10 additions & 6 deletions test/unit/pr_checker.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1267,7 +1267,8 @@ describe('PRChecker', () => {
['Last Jenkins CI successful']
],
error: [
['Last GitHub CI failed']
['1 GitHub CI job(s) failed:'],
[' - test-linux: FAILURE (https://github.com/nodejs/node/runs/12345)']
],
info: [
[`Last Full PR CI on 2018-10-22T04:16:36.458Z: ${jenkins.url}`]
Expand Down Expand Up @@ -1674,7 +1675,8 @@ describe('PRChecker', () => {

const expectedLogs = {
error: [
['Last GitHub CI failed']
['1 GitHub CI job(s) failed:'],
[' - github-actions: FAILURE']
]
};

Expand Down Expand Up @@ -1734,7 +1736,8 @@ describe('PRChecker', () => {

const expectedLogs = {
error: [
['Last GitHub CI failed']
['1 GitHub CI job(s) failed:'],
[' - test-linux: FAILURE (https://github.com/nodejs/node/runs/12345)']
]
};

Expand Down Expand Up @@ -1791,7 +1794,7 @@ describe('PRChecker', () => {

const expectedLogs = {
error: [
['Last GitHub CI failed']
['GitHub CI failed with status: FAILURE']
]
};

Expand Down Expand Up @@ -1867,7 +1870,7 @@ describe('PRChecker', () => {

const expectedLogs = {
error: [
['Last GitHub CI failed']
['GitHub CI failed with status: FAILURE']
]
};

Expand All @@ -1886,7 +1889,8 @@ describe('PRChecker', () => {

const expectedLogs = {
error: [
['Last GitHub CI failed']
['1 GitHub CI job(s) failed:'],
[' - github-actions: FAILURE']
]
};

Expand Down
Loading