@@ -22,7 +22,33 @@ githubClient.authenticate({
22
22
token : process . env . GITHUB_TOKEN
23
23
} )
24
24
25
- function pollAndComment ( owner , repoName , prId , checkNumber ) {
25
+ function pollThenComment ( owner , repoName , prId ) {
26
+ const prInfo = prInfoStr ( { owner, repoName, prId } )
27
+
28
+ // we have to figure out what type of Travis polling we should perform,
29
+ // either by PR #id (as for nodejs.org) or commit sha (for readable-stream)
30
+ travisClient . repos ( owner , repoName ) . builds . get ( ( err , res ) => {
31
+ if ( err ) {
32
+ return console . error ( `! ${ prInfo } Error while retrieving initial builds` , err . stack )
33
+ }
34
+
35
+ const hasAnyPrBuilds = res . builds . some ( ( build ) => build . pull_request )
36
+
37
+ if ( hasAnyPrBuilds ) {
38
+ pollByPrThenComment ( owner , repoName , prId )
39
+ } else {
40
+ pollByCommitThenComment ( owner , repoName , prId )
41
+ }
42
+ } )
43
+ }
44
+
45
+ /**
46
+ * When Travis CI picks up our PR's, we can poll and match builds
47
+ * by their related PR #id.
48
+ *
49
+ * That's the case for nodejs.org.
50
+ */
51
+ function pollByPrThenComment ( owner , repoName , prId , checkNumber ) {
26
52
checkNumber = checkNumber || 1
27
53
28
54
const prInfo = prInfoStr ( { owner, repoName, prId } )
@@ -56,7 +82,75 @@ function pollAndComment (owner, repoName, prId, checkNumber) {
56
82
console . warn ( `! ${ prInfo } Was not able to find matching build, will do check #${ checkNumber + 1 } in 30 seconds` )
57
83
}
58
84
59
- setTimeout ( pollAndComment , 30 * 1000 , owner , repoName , prId , checkNumber + 1 )
85
+ setTimeout ( pollByPrThenComment , 30 * 1000 , owner , repoName , prId , checkNumber + 1 )
86
+ } )
87
+ }
88
+
89
+ /**
90
+ * When Travis CI *doesn't* pick up our PR's, we have to poll and match builds
91
+ * by the last commit SHA of the related PR.
92
+ *
93
+ * This is the case for readable-stream.
94
+ */
95
+ function pollByCommitThenComment ( owner , repoName , prId ) {
96
+ const prInfo = prInfoStr ( { owner, repoName, prId } )
97
+
98
+ githubClient . pullRequests . getCommits ( {
99
+ user : owner ,
100
+ repo : repoName ,
101
+ number : prId
102
+ } , ( err , commitMetas ) => {
103
+ if ( err ) {
104
+ return console . error ( `! ${ prInfo } Got error when retrieving GitHub commits for PR` , err . stack )
105
+ }
106
+
107
+ const lastSha = commitMetas . pop ( ) . sha
108
+ pollTravisBuildBySha ( { owner, repoName, prId, lastSha } )
109
+ console . log ( `* ${ prInfo } Started polling Travis for build by commit ${ lastSha . substr ( 0 , 7 ) } ` )
110
+ } )
111
+ }
112
+
113
+ function pollTravisBuildBySha ( options , checkNumber ) {
114
+ const createGhComment = createGhCommentFn ( options )
115
+ const prInfo = prInfoStr ( options )
116
+ const shaToMatch = options . lastSha
117
+
118
+ checkNumber = checkNumber || 1
119
+
120
+ if ( checkNumber > 100 ) {
121
+ console . warn ( `* ${ prInfo } Was not able to find matching build for PR, stopping poll now :(` )
122
+ return
123
+ }
124
+
125
+ travisClient . repos ( options . owner , options . repoName ) . builds . get ( ( err , res ) => {
126
+ if ( err ) {
127
+ return console . error ( `! ${ prInfo } Got error when retrieving Travis builds` , err . stack )
128
+ }
129
+
130
+ const matchingCommit = res . commits . find ( ( commit ) => commit . sha === shaToMatch )
131
+ if ( ! matchingCommit ) {
132
+ console . warn ( `! ${ prInfo } Travis hasn't picked up last commit yet, will do check #${ checkNumber + 1 } in 30 seconds` )
133
+ return setTimeout ( pollTravisBuildBySha , 30 * 1000 , options , checkNumber + 1 )
134
+ }
135
+
136
+ const lastBuildForCommit = res . builds . find ( ( build ) => build . commit_id === matchingCommit . id )
137
+ if ( lastBuildForCommit ) {
138
+ const lastState = lastBuildForCommit . state
139
+
140
+ if ( lastState === 'passed' ) {
141
+ return createGhComment ( `[Travis build passed](https://travis-ci.org/${ options . owner } /${ options . repoName } /builds/${ lastBuildForCommit . id } ) :+1:` )
142
+ } else if ( lastState === 'failed' ) {
143
+ return createGhComment ( `[Travis build failed](https://travis-ci.org/${ options . owner } /${ options . repoName } /builds/${ lastBuildForCommit . id } ) :-1:` )
144
+ } else if ( ~ [ 'created' , 'started' ] . indexOf ( lastState ) ) {
145
+ console . log ( `* ${ prInfo } "${ lastState } " build found, will do check #${ checkNumber + 1 } in 30 seconds` )
146
+ } else {
147
+ return console . log ( `* ${ prInfo } Unknown build state: "${ lastState } ", stopping polling` )
148
+ }
149
+ } else {
150
+ console . warn ( `! ${ prInfo } Was not able to find matching build by last commit, will do check #${ checkNumber + 1 } in 30 seconds` )
151
+ }
152
+
153
+ setTimeout ( pollTravisBuildBySha , 30 * 1000 , options , checkNumber + 1 )
60
154
} )
61
155
}
62
156
@@ -71,7 +165,7 @@ function createGhCommentFn (options) {
71
165
body : message
72
166
} , ( err , res ) => {
73
167
if ( err ) {
74
- return console . error ( `! ${ prInfo } Error from GitHub` , err . stack )
168
+ return console . error ( `! ${ prInfo } Error while creating GitHub comment ` , err . stack )
75
169
}
76
170
console . log ( `* ${ prInfo } Github comment created` )
77
171
} )
@@ -82,4 +176,4 @@ function prInfoStr (options) {
82
176
return `${ options . owner } /${ options . repoName } /#${ options . prId } `
83
177
}
84
178
85
- exports . pollAndComment = pollAndComment
179
+ exports . pollThenComment = pollThenComment
0 commit comments