@@ -20,9 +20,11 @@ const {
20
20
const {
21
21
JobParser,
22
22
CI_TYPES ,
23
+ CI_PROVIDERS ,
23
24
isLiteCI,
24
25
isFullCI
25
26
} = require ( './ci/ci_type_parser' ) ;
27
+ const { PRBuild } = require ( './ci/ci_result_parser' ) ;
26
28
27
29
const GIT_CONFIG_GUIDE_URL = 'https://github.com/nodejs/node/blob/99b1ada/doc/guides/contributing/pull-requests.md#step-1-fork' ;
28
30
@@ -31,8 +33,9 @@ class PRChecker {
31
33
* @param {{} } cli
32
34
* @param {PRData } data
33
35
*/
34
- constructor ( cli , data , argv ) {
36
+ constructor ( cli , data , request , argv ) {
35
37
this . cli = cli ;
38
+ this . request = request ;
36
39
this . data = data ;
37
40
const {
38
41
pr, reviewers, comments, reviews, commits, collaborators
@@ -66,10 +69,10 @@ class PRChecker {
66
69
return this . argv . waitTimeMultiApproval ;
67
70
}
68
71
69
- checkAll ( checkComments = false ) {
72
+ async checkAll ( checkComments = false ) {
70
73
const status = [
71
74
this . checkCommitsAfterReview ( ) ,
72
- this . checkCI ( ) ,
75
+ await this . checkCI ( ) ,
73
76
this . checkReviewsAndWait ( new Date ( ) , checkComments ) ,
74
77
this . checkMergeableState ( ) ,
75
78
this . checkPRState ( ) ,
@@ -201,32 +204,42 @@ class PRChecker {
201
204
return cis . find ( ci => isFullCI ( ci ) || isLiteCI ( ci ) ) ;
202
205
}
203
206
204
- checkCI ( ) {
205
- const ciType = this . argv . ciType || 'jenkins' ;
206
- if ( ciType === 'jenkins' ) {
207
- return this . checkJenkinsCI ( ) ;
208
- } else if ( ciType === 'github-check' ) {
209
- return this . checkGitHubCI ( ) ;
207
+ async checkCI ( ) {
208
+ const ciType = this . argv . ciType || CI_PROVIDERS . JENKINS ;
209
+ const providers = Object . values ( CI_PROVIDERS ) ;
210
+
211
+ if ( ! providers . includes ( ciType ) ) {
212
+ this . cli . error (
213
+ `Invalid ciType ${ ciType } - must be one of ${ providers . join ( ', ' ) } ` ) ;
214
+ return false ;
210
215
}
211
- this . cli . error ( `Invalid ciType: ${ ciType } ` ) ;
212
- return false ;
216
+
217
+ let status = false ;
218
+ if ( ciType === CI_PROVIDERS . JENKINS ) {
219
+ status = await this . checkJenkinsCI ( ) ;
220
+ } else if ( ciType === CI_PROVIDERS . GITHUB ) {
221
+ status = this . checkGitHubCI ( ) ;
222
+ }
223
+
224
+ return status ;
213
225
}
214
226
215
227
// TODO: we might want to check CI status when it's less flaky...
216
228
// TODO: not all PR requires CI...labels?
217
- checkJenkinsCI ( ) {
218
- const { cli, commits, argv } = this ;
229
+ async checkJenkinsCI ( ) {
230
+ const { cli, commits, request , argv } = this ;
219
231
const { maxCommits } = argv ;
220
232
const thread = this . data . getThread ( ) ;
221
233
const ciMap = new JobParser ( thread ) . parse ( ) ;
234
+
222
235
let status = true ;
223
236
if ( ! ciMap . size ) {
224
237
cli . error ( 'No CI runs detected' ) ;
225
238
this . CIStatus = false ;
226
239
return false ;
227
240
} else if ( ! this . hasFullOrLiteCI ( ciMap ) ) {
228
241
status = false ;
229
- cli . error ( 'No full CI runs or lite CI runs detected' ) ;
242
+ cli . error ( 'No full or lite Jenkins CI runs detected' ) ;
230
243
}
231
244
232
245
let lastCI ;
@@ -236,7 +249,8 @@ class PRChecker {
236
249
if ( ! lastCI || lastCI . date < ci . date ) {
237
250
lastCI = {
238
251
typeName : name ,
239
- date : ci . date
252
+ date : ci . date ,
253
+ jobId : ci . jobid
240
254
} ;
241
255
}
242
256
}
@@ -270,6 +284,16 @@ class PRChecker {
270
284
cli . warn ( infoMsg ) ;
271
285
}
272
286
}
287
+
288
+ // Check the last CI run for its results.
289
+ const build = new PRBuild ( cli , request , lastCI . jobId ) ;
290
+ const { result, failures } = await build . getResults ( ) ;
291
+
292
+ if ( result === 'FAILURE' ) {
293
+ cli . error (
294
+ `${ failures . length } failure(s) on the last Jenkins CI run` ) ;
295
+ status = false ;
296
+ }
273
297
}
274
298
275
299
this . CIStatus = status ;
@@ -298,12 +322,12 @@ class PRChecker {
298
322
// GitHub new Check API
299
323
for ( const { status, conclusion } of checkSuites . nodes ) {
300
324
if ( status !== 'COMPLETED' ) {
301
- cli . error ( 'CI is still running' ) ;
325
+ cli . error ( 'GitHub CI is still running' ) ;
302
326
return false ;
303
327
}
304
328
305
329
if ( ! [ 'SUCCESS' , 'NEUTRAL' ] . includes ( conclusion ) ) {
306
- cli . error ( 'Last CI failed' ) ;
330
+ cli . error ( 'Last GitHub CI failed' ) ;
307
331
return false ;
308
332
}
309
333
}
@@ -312,17 +336,17 @@ class PRChecker {
312
336
if ( commit . status ) {
313
337
const { state } = commit . status ;
314
338
if ( state === 'PENDING' ) {
315
- cli . error ( 'CI is still running' ) ;
339
+ cli . error ( 'GitHub CI is still running' ) ;
316
340
return false ;
317
341
}
318
342
319
343
if ( ! [ 'SUCCESS' , 'EXPECTED' ] . includes ( state ) ) {
320
- cli . error ( 'Last CI failed' ) ;
344
+ cli . error ( 'Last GitHub CI failed' ) ;
321
345
return false ;
322
346
}
323
347
}
324
348
325
- cli . info ( 'Last CI run was successful' ) ;
349
+ cli . info ( 'Last GitHub CI successful' ) ;
326
350
this . CIStatus = true ;
327
351
return true ;
328
352
}
0 commit comments