forked from nodejs/github-bot
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtrigger-jenkins-build.js
More file actions
137 lines (113 loc) · 4.11 KB
/
trigger-jenkins-build.js
File metadata and controls
137 lines (113 loc) · 4.11 KB
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
130
131
132
133
134
135
136
137
'use strict'
const request = require('request')
const githubClient = require('../lib/github-client')
const botUsername = require('../lib/bot-username')
const { createPrComment } = require('../lib/github-comment')
const jenkinsApiCredentials = process.env.JENKINS_API_CREDENTIALS || ''
function wasBotMentionedInCiComment (commentBody) {
const atBotName = new RegExp(`^@${botUsername} run CI`, 'mi')
return commentBody.match(atBotName) !== null
}
// Name for the Jenkins job should be triggered for a given repository
function getJobNameForRepo (repo) {
// e.g. JENKINS_JOB_CITGM = node-test-pull-request-lite-pipeline
return process.env[`JENKINS_JOB_${repo.toUpperCase()}`] || ''
}
// Authentication token configured per Jenkins job needed when triggering a build,
// this is set per job in Configure -> Build Triggers -> Trigger builds remotely
function buildTokenForRepo (repo) {
// e.g. JENKINS_BUILD_TOKEN_CITGM
return process.env[`JENKINS_BUILD_TOKEN_${repo.toUpperCase()}`] || ''
}
function buildParametersForRepo (options, repo) {
if (repo === 'citgm') {
return [{
name: 'GIT_REMOTE_REF',
value: `refs/pull/${options.number}/head`
}]
} else {
return [
{ name: 'CERTIFY_SAFE', value: 'true' },
{ name: 'GITHUB_ORG', value: 'nodejs' },
{ name: 'REPO_NAME', value: 'node' },
{ name: 'PR_ID', value: options.number },
{ name: 'REBASE_ONTO', value: '' }
]
}
}
function triggerBuild (options, cb) {
const { repo } = options
const base64Credentials = Buffer.from(jenkinsApiCredentials).toString('base64')
const authorization = `Basic ${base64Credentials}`
const jobName = getJobNameForRepo(repo)
const buildAuthToken = buildTokenForRepo(repo)
if (!jobName) {
return cb(new TypeError(`Will not trigger Jenkins build because $JENKINS_JOB_${repo.toUpperCase()} is not set`))
}
if (!buildAuthToken) {
return cb(new TypeError(`Will not trigger Jenkins build because $JENKINS_BUILD_TOKEN_${repo.toUpperCase()} is not set`))
}
options.logger.debug('Triggering Jenkins build')
request.post({
uri: `https://ci.nodejs.org/blue/rest/organizations/jenkins/pipelines/${jobName}/runs/`,
headers: { authorization },
qs: { token: buildAuthToken },
json: { parameters: buildParametersForRepo(options, repo) }
}, (err, response) => {
if (err) {
return cb(err)
} else if (response.statusCode !== 200) {
return cb(new Error(`Expected 200 from Jenkins, got ${response.statusCode}`))
}
cb(null,
`https://ci.nodejs.org/blue/organizations/jenkins/${jobName}/detail/${jobName}/${response.body.id}/pipeline`)
})
}
function triggerBuildIfValid (options) {
const { owner, repo, author, logger } = options
githubClient.repos.checkCollaborator({ owner, repo, username: author }, function onResponse (err) {
if (err) {
return logger.debug(`Ignoring comment to me by @${options.author} because they are not a repo collaborator`)
}
triggerBuild(options, function onBuildTriggered (err, buildUrl) {
if (err) {
logger.error(err, 'Error while triggering Jenkins build')
return createPrComment(options, `@${options.author} Sadly, an error occurred when I tried to trigger a build. :(`)
}
createPrComment(options, `@${options.author} build started: ${buildUrl}`)
logger.info({ buildUrl }, 'Jenkins build started')
})
})
}
module.exports = (app) => {
app.on('issue_comment.created', handleCommentCreated)
app.on('pull_request.opened', handlePullCreated)
}
function handleCommentCreated (event, owner, repo) {
const { number, logger, comment } = event
const commentAuthor = comment.user.login
const options = {
owner,
repo,
number,
logger,
author: commentAuthor
}
if (wasBotMentionedInCiComment(comment.body)) {
triggerBuildIfValid(options)
}
}
function handlePullCreated (event, owner, repo) {
const { number, logger, pull_request } = event
const pullRequestAuthor = pull_request.user.login
const options = {
owner,
repo,
number,
logger,
author: pullRequestAuthor
}
if (repo === 'node') {
triggerBuildIfValid(options)
}
}