-
Notifications
You must be signed in to change notification settings - Fork 117
/
Copy pathpush-jenkins-update.js
129 lines (107 loc) · 3.67 KB
/
push-jenkins-update.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
'use strict'
const githubClient = require('./github-client')
const { createPrComment } = require('./github-comment')
function pushStarted (options, build, cb) {
const pr = findPrInRef(build.ref)
// create unique logger which is easily traceable for every subsequent log statement
const traceFields = { pr, job: build.identifier, gitRef: build.ref, status: build.status }
const logger = options.logger.child(traceFields, true)
const optsWithPr = Object.assign({ pr }, options)
if (build.status === 'pending') {
switch (build.identifier) {
case 'node-test-pull-request':
createPrComment(Object.assign({ issue_number: pr }, options), `CI: ${build.url}`)
break
case 'node-test-pull-request-lite-pipeline':
createPrComment(Object.assign({ issue_number: pr }, options), `Lite-CI: ${build.url}`)
break
default:
break
}
}
findLatestCommitInPr(optsWithPr).then(latestCommit => {
const statusOpts = Object.assign({
sha: latestCommit.sha,
url: build.url,
context: build.identifier,
state: build.status,
message: build.message || 'running tests'
}, options)
createGhStatus(statusOpts, logger).then(cb).catch(cb)
}, err => {
logger.error(err, 'Got error when retrieving GitHub commits for PR')
return cb(err)
})
}
function pushEnded (options, build, cb) {
const pr = findPrInRef(build.ref)
// create unique logger which is easily traceable for every subsequent log statement
const traceFields = { pr, job: build.identifier, gitRef: build.ref, status: build.status }
const logger = options.logger.child(traceFields, true)
const optsWithPr = Object.assign({ pr }, options)
findLatestCommitInPr(optsWithPr).then(latestCommit => {
const statusOpts = Object.assign({
sha: latestCommit.sha,
url: build.url,
context: build.identifier,
state: build.status,
message: build.message || 'all tests passed'
}, options)
createGhStatus(statusOpts, logger).then(cb, cb)
}, err => {
logger.error(err, 'Got error when retrieving GitHub commits for PR')
return cb(err)
})
}
function findPrInRef (gitRef) {
// refs/pull/12345/head
return parseInt(gitRef.split('/')[2], 10)
}
async function findLatestCommitInPr (options, pageNumber = 1) {
const res = await githubClient.pulls.listCommits({
owner: options.owner,
repo: options.repo,
pull_number: options.pr,
page: pageNumber,
per_page: 100
})
const commitMetas = res.data || []
const lastPageURL = githubClient.hasLastPage(res)
if (lastPageURL) {
return findLatestCommitInPr(options, pageNumberFromURL(lastPageURL))
}
const lastCommitMeta = commitMetas.pop()
const lastCommit = {
sha: lastCommitMeta.sha,
date: lastCommitMeta.commit.committer.date
}
return lastCommit
}
async function createGhStatus (options, logger) {
try {
await githubClient.repos.createStatus({
owner: options.owner,
repo: options.repo,
sha: options.sha,
target_url: options.url,
context: options.context,
state: options.state,
description: options.message
})
} catch (err) {
logger.error(err, 'Error while updating Jenkins / GitHub PR status')
throw err
}
logger.info('Jenkins / Github PR status updated')
}
function validate (payload) {
const isString = (param) => typeof (payload[param]) === 'string'
return ['identifier', 'status', 'message', 'commit', 'url'].every(isString)
}
function pageNumberFromURL (githubUrl) {
return new URL(githubUrl).searchParams.get('page')
}
exports.validate = validate
exports.pushStarted = pushStarted
exports.pushEnded = pushEnded
exports.findLatestCommitInPr = findLatestCommitInPr