Skip to content

Commit

Permalink
feat: check Actions and handle doc-only changes
Browse files Browse the repository at this point in the history
Doc-only changes don't need a full Jenkins CI, instead we can check
if the last Actions run was successful. Therefore this commit also adds
check for Action runs. Jenkins CI messages were improved as well.

Fix: nodejs#324
Fix: nodejs/node#32335
Fix: nodejs/node#29770
  • Loading branch information
mmarchini committed Aug 9, 2020
1 parent 5730faf commit 5ce5265
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 12 deletions.
3 changes: 2 additions & 1 deletion lib/ci/ci_type_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ const CI_TYPE_ENUM = {

const CI_PROVIDERS = {
JENKINS: 'jenkins',
GITHUB: 'github-check'
GITHUB: 'github-check',
NODEJS: 'nodejs'
};

const { JOB_CI, FULL_CI } = CI_TYPE_ENUM;
Expand Down
81 changes: 77 additions & 4 deletions lib/pr_checker.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ class PRChecker {
}

async checkCI() {
const ciType = this.argv.ciType || CI_PROVIDERS.JENKINS;
const ciType = this.argv.ciType || CI_PROVIDERS.NODEJS;
const providers = Object.values(CI_PROVIDERS);

if (!providers.includes(ciType)) {
Expand All @@ -218,6 +218,8 @@ class PRChecker {
status = await this.checkJenkinsCI();
} else if (ciType === CI_PROVIDERS.GITHUB) {
status = this.checkGitHubCI();
} else if (ciType === CI_PROVIDERS.NODEJS) {
status &= await this.checkNodejsCI();
}

return status;
Expand All @@ -233,7 +235,7 @@ class PRChecker {

let status = true;
if (!ciMap.size) {
cli.error('No CI runs detected');
cli.error('No Jenkins CI runs detected');
this.CIStatus = false;
return false;
} else if (!this.hasFullCI(ciMap)) {
Expand Down Expand Up @@ -292,17 +294,61 @@ class PRChecker {
cli.error(
`${failures.length} failure(s) on the last Jenkins CI run`);
status = false;
// NOTE(mmarchini): not sure why PEDING returns null
} else if (result === null) {
cli.error(
'Last Jenkins CI still running');
status = false;
} else {
cli.ok('Last Jenkins CI successful');
}
}

this.CIStatus = status;
return status;
}

checkActionsCI() {
const { cli, commits } = this;

if (!commits || commits.length === 0) {
cli.error('No commits detected');
return false;
}

// NOTE(mmarchini): we only care about the last commit. Maybe in the future
// we'll want to check all commits for a successful CI.
const { commit } = commits[commits.length - 1];

this.CIStatus = false;
const checkSuites = commit.checkSuites || { nodes: [] };
if (!commit.status && checkSuites.nodes.length === 0) {
cli.error('No GitHub CI runs detected');
return false;
}

// GitHub new Check API
for (const { status, conclusion } of checkSuites.nodes) {
if (status !== 'COMPLETED') {
cli.error('GitHub CI is still running');
return false;
}

if (!['SUCCESS', 'NEUTRAL'].includes(conclusion)) {
cli.error('Last GitHub CI failed');
return false;
}
}

cli.ok('Last GitHub Actions successful');
this.CIStatus = true;
return true;
}

checkGitHubCI() {
const { cli, commits } = this;

if (!commits) {
if (!commits || commits.length === 0) {
cli.error('No commits detected');
return false;
}
Expand All @@ -314,7 +360,7 @@ class PRChecker {
this.CIStatus = false;
const checkSuites = commit.checkSuites || { nodes: [] };
if (!commit.status && checkSuites.nodes.length === 0) {
cli.error('No CI runs detected');
cli.error('No GitHub CI runs detected');
return false;
}

Expand Down Expand Up @@ -350,6 +396,33 @@ class PRChecker {
return true;
}

isOnlyDocChanges() {
const { cli, pr } = this;

// NOTE(mmarchini): if files not present, fallback
// to old behavior. This should only be the case on old tests
// TODO(mmarchini): add files to all fixtures on old tests
if (!pr.files) {
return false;
}

for (const { path } of pr.files.nodes) {
if (!path.endsWith('.md')) {
return false;
}
}
cli.info('Doc-only changes');
return true;
}

async checkNodejsCI() {
let status = this.checkActionsCI();
if (!this.isOnlyDocChanges()) {
status &= await this.checkJenkinsCI();
}
return status;
}

checkAuthor() {
const { cli, commits, pr } = this;

Expand Down
5 changes: 5 additions & 0 deletions lib/queries/PR.gql
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ query PR($prid: Int!, $owner: String!, $repo: String!) {
name
}
},
files(first: 100) {
nodes {
path
}
},
title,
baseRefName,
headRefName,
Expand Down
2 changes: 1 addition & 1 deletion lib/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class Session {
}

get ciType() {
return this.config.ciType || 'jenkins';
return this.config.ciType || 'nodejs';
}

get pullName() {
Expand Down
35 changes: 29 additions & 6 deletions test/unit/pr_checker.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,8 @@ describe('PRChecker', () => {

const expectedLogs = {
error: [
['No CI runs detected']
['No GitHub CI runs detected'],
['No Jenkins CI runs detected']
]
};

Expand All @@ -646,6 +647,12 @@ describe('PRChecker', () => {
const cli = new TestCLI();

const expectedLogs = {
ok: [
['Last Jenkins CI successful']
],
error: [
['No commits detected']
],
info: [
[
'Last Full PR CI on 2017-10-25T04:16:36.458Z: ' +
Expand Down Expand Up @@ -693,7 +700,7 @@ describe('PRChecker', () => {
const checker = new PRChecker(cli, data, {}, argv);

const status = await checker.checkCI();
assert(status);
assert(!status);
cli.assertCalledWith(expectedLogs, {
ignore: ['startSpinner', 'updateSpinner', 'stopSpinner']
});
Expand All @@ -712,6 +719,12 @@ describe('PRChecker', () => {
],
info: [
['Last Full PR CI on 2017-10-24T11:19:25Z: https://ci.nodejs.org/job/node-test-pull-request/10984/']
],
ok: [
['Last Jenkins CI successful']
],
error: [
['No GitHub CI runs detected']
]
};

Expand Down Expand Up @@ -754,7 +767,12 @@ describe('PRChecker', () => {
'https://ci.nodejs.org/job/node-test-pull-request/12984/'
]
],
error: []
ok: [
['Last Jenkins CI successful']
],
error: [
['No GitHub CI runs detected']
]
};

const checker = new PRChecker(cli, {
Expand Down Expand Up @@ -792,7 +810,12 @@ describe('PRChecker', () => {
'https://ci.nodejs.org/job/node-test-pull-request/12984/'
]
],
error: []
ok: [
['Last Jenkins CI successful']
],
error: [
['No GitHub CI runs detected']
]
};

const checker = new PRChecker(cli, {
Expand Down Expand Up @@ -835,7 +858,7 @@ describe('PRChecker', () => {

const expectedLogs = {
error: [
['No CI runs detected']
['No GitHub CI runs detected']
]
};

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

const expectedLogs = {
error: [
['No CI runs detected']
['No GitHub CI runs detected']
]
};

Expand Down

0 comments on commit 5ce5265

Please sign in to comment.