Skip to content

Commit

Permalink
Proxy Jenkins build status to GitHub (#35)
Browse files Browse the repository at this point in the history
This enables Jenkins jobs to push updates as POST requests to the bot,
which proxies the information given to the GitHub status API, resulting in
PRs getting inline build status like we're used to with Travis CI.
  • Loading branch information
phillipj committed May 11, 2016
1 parent a9fac8a commit 39f2c49
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 0 deletions.
46 changes: 46 additions & 0 deletions lib/push-jenkins-update.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
'use strict'

const githubClient = require('./github-client')

function pushJenkinsUpdate (options, build) {
const statusOpts = extendWithBuildData(options, build)
const createGhStatus = createGhStatusFn(statusOpts)

createGhStatus(build.status, build.message)
}

function createGhStatusFn (options) {
const prInfo = prInfoStr(options)

return (state, message) => {
githubClient.statuses.create({
user: options.owner,
repo: options.repoName,
sha: options.sha,
target_url: options.url,
context: options.context,
state: state,
description: message
}, (err, res) => {
if (err) {
return console.error(`! ${prInfo} Error while updating Jenkins / GitHub PR status`, err)
}
console.log(`* ${prInfo} Jenkins / Github PR status updated to '${state}'`)
})
}
}

function extendWithBuildData (options, build) {
return Object.assign({
sha: build.commit,
url: build.url,
context: build.identifier
}, options)
}

function prInfoStr (options) {
const shortSha = options.sha.substr(0, 7)
return `${options.owner}/${options.repoName}/${shortSha}`
}

module.exports = pushJenkinsUpdate
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@
},
"devDependencies": {
"eventsource": "^0.2.1",
"nock": "^8.0.0",
"nodemon": "^1.9.1",
"request": "^2.72.0",
"standard": "^6.0.7",
"supertest": "^1.2.0",
"tap": "^5.7.1"
}
}
14 changes: 14 additions & 0 deletions scripts/node-jenkins-status.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
'use strict'

const pushJenkinsUpdate = require('../lib/push-jenkins-update')

module.exports = function (app) {
app.post('/node/jenkins', (req, res) => {
pushJenkinsUpdate({
owner: 'nodejs',
repoName: 'node'
}, req.body)

res.status(201).end()
})
}
7 changes: 7 additions & 0 deletions test/_fixtures/error-payload.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"identifier": "test/arm",
"status": "failure",
"message": "tests failed",
"commit": "8a5fec2a6bade91e544a30314d7cf21f8a200de1",
"url": "https://ci.nodejs.org/job/node-test-commit-arm/3087/"
}
7 changes: 7 additions & 0 deletions test/_fixtures/pending-payload.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"identifier": "test/linux",
"status": "pending",
"message": "checking for errors",
"commit": "8a5fec2a6bade91e544a30314d7cf21f8a200de1",
"url": "https://ci.nodejs.org/job/node-test-commit-linux/3176/"
}
7 changes: 7 additions & 0 deletions test/_fixtures/success-payload.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"identifier": "test/osx",
"status": "success",
"message": "tests passed",
"commit": "8a5fec2a6bade91e544a30314d7cf21f8a200de1",
"url": "https://ci.nodejs.org/job/node-test-commit-osx/3157/"
}
62 changes: 62 additions & 0 deletions test/push-jenkins-update.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
'use strict'

const tap = require('tap')
const fs = require('fs')
const path = require('path')
const url = require('url')
const nock = require('nock')
const supertest = require('supertest')

const app = require('../app')

tap.test('Sends POST requests to https://api.github.com/repos/nodejs/node/statuses/<SHA>', (t) => {
const fixture = readFixture('success-payload.json')
const scope = nock('https://api.github.com')
.filteringPath(ignoreQueryParams)
.post('/repos/nodejs/node/statuses/8a5fec2a6bade91e544a30314d7cf21f8a200de1')
.reply(201)

t.plan(1)
t.tearDown(() => scope.done())

supertest(app)
.post('/node/jenkins')
.send(fixture)
.expect(201)
.end((err, res) => {
t.equal(err, null)
})
})

tap.test('Forwards payload provided in incoming POST to GitHub status API', (t) => {
const fixture = readFixture('success-payload.json')
const scope = nock('https://api.github.com')
.filteringPath(ignoreQueryParams)
.post('/repos/nodejs/node/statuses/8a5fec2a6bade91e544a30314d7cf21f8a200de1', {
state: 'success',
context: 'test/osx',
description: 'tests passed',
target_url: 'https://ci.nodejs.org/job/node-test-commit-osx/3157/'
})
.reply(201)

t.plan(1)
t.tearDown(() => scope.done())

supertest(app)
.post('/node/jenkins')
.send(fixture)
.expect(201)
.end((err, res) => {
t.equal(err, null)
})
})

function ignoreQueryParams (pathAndQuery) {
return url.parse(pathAndQuery, true).pathname
}

function readFixture (fixtureName) {
const content = fs.readFileSync(path.join(__dirname, '_fixtures', fixtureName)).toString()
return JSON.parse(content)
}

0 comments on commit 39f2c49

Please sign in to comment.