diff --git a/scripts/trigger-jenkins-build.js b/scripts/trigger-jenkins-build.js deleted file mode 100644 index 44a5b53b..00000000 --- a/scripts/trigger-jenkins-build.js +++ /dev/null @@ -1,118 +0,0 @@ -'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: 'PR_ID', value: options.number } - ] - } -} - -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') - - return new Promise((resolve, reject) => { - 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, body) => { - if (err) { - return reject(err) - } else if (response.statusCode !== 200) { - return reject(new Error(`Expected 200 from Jenkins, got ${response.statusCode}: ${body}`)) - } - - resolve({ jobName, jobId: response.body.id }) - }) - }) -} - -async function triggerBuildIfValid (options) { - const { owner, repo, author, logger } = options - - try { - await githubClient.repos.checkCollaborator({ owner, repo, username: author }) - } catch (_err) { - logger.debug(`Ignoring comment to me by @${options.author} because they are not a repo collaborator`) - return - } - - try { - const result = await triggerBuild(options) - const jobUrl = `https://ci.nodejs.org/job/${result.jobName}/${result.jobId}` - logger.info({ jobUrl }, 'Jenkins build started') - - return createPrComment(options, `Lite-CI: ${jobUrl}`) - } catch (err) { - logger.error(err, 'Error while triggering Jenkins build') - throw err - } -} - -module.exports = (app, events) => { - events.on('issue_comment.created', handleCommentCreated) - events.on('pull_request.opened', handlePullCreated) -} - -function handleCommentCreated (event, owner, repo) { - const { number, logger, comment: { body, user: { login: author } } } = event - const options = { owner, repo, number, logger, author } - - return wasBotMentionedInCiComment(body) ? triggerBuildIfValid(options) : Promise.resolve() -} - -function handlePullCreated (event, owner, repo) { - const { number, logger, pull_request: { user: { login: author } } } = event - const options = { owner, repo, number, logger, author } - - return repo === 'node' ? triggerBuildIfValid(options) : Promise.resolve() -} diff --git a/test/integration/trigger-jenkins-build.test.js b/test/integration/trigger-jenkins-build.test.js deleted file mode 100644 index 2548c4c5..00000000 --- a/test/integration/trigger-jenkins-build.test.js +++ /dev/null @@ -1,66 +0,0 @@ -'use strict' - -const tap = require('tap') -const url = require('url') -const nock = require('nock') -const supertest = require('supertest') -const proxyquire = require('proxyquire') -const readFixture = require('../read-fixture') - -const { app, events } = proxyquire('../../app', { - './github-secret': { - isValid: () => true, - - // necessary to make makes proxyquire return this stub - // whenever *any* module tries to require('./github-secret') - '@global': true - } -}) - -require('../../scripts/trigger-jenkins-build')(app, events) - -tap.test('Sends POST request to https://ci.nodejs.org', (t) => { - const originalJobUrlValue = process.env.JENKINS_JOB_URL_NODE - const originalTokenValue = process.env.JENKINS_BUILD_TOKEN_NODE - process.env.JENKINS_JOB_NODE = 'node-test-pull-request-lite-pipeline' - process.env.JENKINS_BUILD_TOKEN_NODE = 'myToken' - - const webhookPayload = readFixture('pull-request-opened.json') - const pipelineUrl = 'https://ci.nodejs.org/job/node-test-pull-request-lite-pipeline/1' - - const collaboratorsScope = nock('https://api.github.com') - .filteringPath(ignoreQueryParams) - .get('/repos/nodejs/node/collaborators/phillipj') - .reply(200, { permission: 'admin' }) - const ciJobScope = nock('https://ci.nodejs.org') - .filteringPath(ignoreQueryParams) - .post('/blue/rest/organizations/jenkins/pipelines/node-test-pull-request-lite-pipeline/runs/') - .reply(200, { id: 1 }, {}) - - const commentScope = nock('https://api.github.com') - .filteringPath(ignoreQueryParams) - .post('/repos/nodejs/node/issues/19/comments', { body: `Lite-CI: ${pipelineUrl}` }) - .reply(200) - - t.plan(1) - t.tearDown(() => { - collaboratorsScope.done() - ciJobScope.done() - commentScope.done() - }) - - supertest(app) - .post('/hooks/github') - .set('x-github-event', 'pull_request') - .send(webhookPayload) - .expect(200) - .end((err, res) => { - process.env.JENKINS_JOB_URL_NODE = originalJobUrlValue - process.env.JENKINS_BUILD_TOKEN_NODE = originalTokenValue - t.equal(err, null) - }) -}) - -function ignoreQueryParams (pathAndQuery) { - return url.parse(pathAndQuery, true).pathname -}