Skip to content

Commit 55e7fcb

Browse files
committed
Handled errors and mapped more Jenkins build statuses -> GH statuses
1 parent 15f4b71 commit 55e7fcb

File tree

2 files changed

+69
-14
lines changed

2 files changed

+69
-14
lines changed

lib/poll-jenkins.js

Lines changed: 69 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,88 @@ const request = require('request')
44

55
const 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

3179
function 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+
54110
function prInfoStr (options) {
55111
return `nodejs/node/#${options.prId}`
56112
}

scripts/node-jenkins-status.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
const pollJenkins = require('../lib/poll-jenkins')
44

55
module.exports = function (app) {
6-
76
// to trigger polling manually
87
app.get('/jenkins/:prId', (req, res) => {
98
const prId = req.params.prId

0 commit comments

Comments
 (0)