diff --git a/scripts/trigger-jenkins-build.js b/scripts/trigger-jenkins-build.js index 80a53eea..bea53509 100644 --- a/scripts/trigger-jenkins-build.js +++ b/scripts/trigger-jenkins-build.js @@ -34,15 +34,39 @@ function buildTokenForRepo (repo) { 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: 'TARGET_GITHUB_ORG', + value: 'nodejs' + }, + { + name: 'TARGET_REPO_NAME', + value: 'node' + }, + { + name: 'PR_ID', + value: options.number + } + ] + } +} + function triggerBuild (options, cb) { const { repo } = options const base64Credentials = new Buffer(jenkinsApiCredentials).toString('base64') const authorization = `Basic ${base64Credentials}` - const buildParameters = [{ - name: 'GIT_REMOTE_REF', - value: `refs/pull/${options.number}/head` - }] - const payload = JSON.stringify({ parameter: buildParameters }) + + const payload = JSON.stringify({ parameter: buildParametersForRepo(options, repo) }) const uri = buildUrlForRepo(repo) const buildAuthToken = buildTokenForRepo(repo) @@ -124,4 +148,33 @@ module.exports = (app) => { githubClient.repos.checkCollaborator({ owner, repo, username: commentAuthor }, triggerBuildWhenCollaborator) }) }) + + app.on('pull_request.opened', function handlePullCreated (event, owner, repo) { + const { number, logger, pull_request } = event + const pullRequestAuthor = pull_request.user.login + const options = { + owner, + repo, + number, + logger + } + + function logBuildStarted (err) { + if (err) { + logger.error(err, 'Error while triggering Jenkins build') + } else { + logger.info('Jenkins build started') + } + } + + function triggerBuildWhenCollaborator (err) { + if (err) { + return logger.debug(`Ignoring comment to me by @${pullRequestAuthor} because they are not a repo collaborator`) + } + + triggerBuild(options, replyToCollabWithBuildStarted) + } + + githubClient.repos.checkCollaborator({ owner, repo, username: pullRequestAuthor }, triggerBuildWhenCollaborator) + }) } diff --git a/test/integration/trigger-jenkins-build.test.js b/test/integration/trigger-jenkins-build.test.js new file mode 100644 index 00000000..8a81dd7e --- /dev/null +++ b/test/integration/trigger-jenkins-build.test.js @@ -0,0 +1,60 @@ +'use strict' + +const tap = require('tap') +const url = require('url') +const nock = require('nock') +const supertest = require('supertest') +const proxyquire = require('proxyquire') +const lolex = require('lolex') +const readFixture = require('../read-fixture') + +const app = proxyquire('../../app', { + './github-secret': { + isValid: () => true, + + // necessary to make makes proxyquire return this stub + // whenever *any* module tries to require('./github-secret') + '@global': true + } +}) + +tap.test('Sends POST request to https://ci.nodejs.org', (t) => { + const clock = lolex.install() + + const originalJobUrlValue = process.env.JENKINS_JOB_URL_NODE + const originalTokenValue = process.env.JENKINS_BUILD_TOKEN_NODE + process.env.JENKINS_JOB_URL_NODE = 'https://ci.nodejs.org/job/node-test-pull-request' + process.env.JENKINS_BUILD_TOKEN_NODE = 'myToken' + + const webhookPayload = readFixture('pull-request-opened.json') + + 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('/job/node-test-pull-request/build') + .reply(201, '', { + 'Location': 'https://ci.nodejs.org/job/node-test-pull-request/1' + }) + + t.plan(1) + t.tearDown(() => collaboratorsScope.done() && ciJobScope.done() && clock.uninstall()) + + 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 + clock.runAll() + t.equal(err, null) + }) +}) + +function ignoreQueryParams (pathAndQuery) { + return url.parse(pathAndQuery, true).pathname +}