@@ -4,40 +4,88 @@ const request = require('request')
44
55const githubClient = require ( './github-client' )
66
7- const sixtySeconds = 60 * 1000 ;
7+ const sixtySeconds = 60 * 1000
8+ const jenkinsToGhStatusMap = {
9+ 'SUCCESS' : {
10+ state : 'success' ,
11+ message : 'all tests passed'
12+ } ,
13+ 'FAILURE' : {
14+ state : 'failure' ,
15+ message : 'build failure'
16+ } ,
17+ 'ABORTED' : {
18+ state : 'error' ,
19+ message : 'build aborted'
20+ } ,
21+ 'UNSTABLE' : {
22+ state : 'error' ,
23+ message : 'build unstable'
24+ }
25+ }
826
9- function pollJenkins ( options , checkNumber ) {
27+ /**
28+ * NOTES TO SELF:
29+ *
30+ * Jenkins build could be matched by related PR by filtering on build parameters:
31+ * request -> build.actions.find(parameters !== undefined).filter({ name: 'PR_ID' && value: <INSERT-PR-ID-HERE> })
32+ * example response: https://ci.nodejs.org/job/node-test-pull-request/2460/api/json
33+ */
34+
35+ function pollJenkins ( options , checkNumber ) {
1036 const url = `https://ci.nodejs.org/job/node-test-pull-request/${ options . prId } /api/json`
1137 checkNumber = checkNumber || 1
1238
13- request ( { url, json : true } , ( err , response , data ) => {
39+ // we should probably not poll forever .. lets stop after 420 polls (7 hours)
40+ if ( checkNumber >= 420 ) {
41+ return console . warn ( `* ${ prInfoStr ( options ) } Wasn't able to a conclusive build result, stopping poll now :(` )
42+ }
43+
44+ request ( { url, json : true } , ( err , response , build ) => {
1445 const nextCheckNumber = checkNumber + 1
1546
16- if ( ! err ) {
17- const buildResult = data . result
47+ if ( err ) {
48+ console . error ( `* ${ prInfoStr ( options ) } Error when requesting Jenkins API, will do check #${ checkNumber + 1 } in one minute. Error: ${ err } ` )
49+ return setTimeout ( pollJenkins , sixtySeconds , options , nextCheckNumber )
50+ }
1851
19- if ( buildResult === 'SUCCESS' ) {
20- console . log ( `* ${ prInfoStr ( options ) } CI build was a success` )
21- return
22- }
52+ if ( response . statusCode === 404 ) {
53+ console . log ( `* ${ prInfoStr ( options ) } Jenkins build not found yet, will do check #${ checkNumber + 1 } in one minute` )
54+ return setTimeout ( pollJenkins , sixtySeconds , options , nextCheckNumber )
2355 }
2456
57+ // we should have enough data to push a github status update
58+ const buildResult = build . result
59+ const isFinished = buildResult !== null
60+ const optsWithSha = extendWithLastCommitSha ( options , build )
61+ const createGhStatus = createGhStatusFn ( optsWithSha )
62+
63+ const matchedGhStatus = jenkinsToGhStatusMap [ buildResult ]
64+
65+ if ( matchedGhStatus ) {
66+ return createGhStatus ( matchedGhStatus . state , matchedGhStatus . message )
67+ } else if ( isFinished ) {
68+ return console . error ( `! ${ prInfoStr ( options ) } Unknown Jenkins build result '${ buildResult } ', aborting poll for this PR` )
69+ }
70+
71+ // as build isn't finished yet, we'll have to keep polling Jenkins for new build status
2572 console . log ( `* ${ prInfoStr ( options ) } Build not finished yet, will do check #${ checkNumber + 1 } in one minute` )
73+ createGhStatus ( 'pending' , 'build in progress' )
2674
27- setTimeout ( pollJenkins , sixtySeconds , prId , nextCheckNumber )
75+ setTimeout ( pollJenkins , sixtySeconds , options , nextCheckNumber )
2876 } )
2977}
3078
3179function createGhStatusFn ( options ) {
3280 const prInfo = prInfoStr ( options )
3381
34- return ( state , travisId , message ) => {
82+ return ( state , message ) => {
3583 const buildUrl = `https://ci.nodejs.org/job/node-test-pull-request/${ options . prId } `
3684
3785 githubClient . statuses . create ( {
3886 user : options . owner ,
3987 repo : options . repoName ,
40- sha : options . lastCommit . sha ,
88+ sha : options . sha ,
4189 target_url : buildUrl ,
4290 context : 'Jenkins CI via nodejs-github-bot' ,
4391 state : state ,
@@ -46,11 +94,19 @@ function createGhStatusFn (options) {
4694 if ( err ) {
4795 return console . error ( `! ${ prInfo } Error while updating Jenkins / GitHub PR status` , err )
4896 }
49- console . log ( `* ${ prInfo } Jenkins / Github PR status updated` )
97+ console . log ( `* ${ prInfo } Jenkins / Github PR status updated to ' ${ state } ' ` )
5098 } )
5199 }
52100}
53101
102+ function extendWithLastCommitSha ( options , build ) {
103+ const lastChangeSet = build . changeSet . items [ 0 ]
104+
105+ return Object . assign ( {
106+ sha : lastChangeSet . commitId
107+ } , options )
108+ }
109+
54110function prInfoStr ( options ) {
55111 return `nodejs/node/#${ options . prId } `
56112}
0 commit comments