refactor [shippable] service (#2576)
This commit is contained in:
@@ -1,16 +1,44 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const LegacyService = require('../legacy-service')
|
const BaseJsonService = require('../base-json')
|
||||||
const { makeBadgeData: getBadgeData } = require('../../lib/badge-data')
|
const Joi = require('joi')
|
||||||
const { checkErrorResponse } = require('../../lib/error-helper')
|
const { NotFound } = require('../errors')
|
||||||
|
|
||||||
|
// source: https://github.com/badges/shields/pull/1362#discussion_r161693830
|
||||||
|
const statusCodes = {
|
||||||
|
0: { color: '#5183A0', label: 'waiting' },
|
||||||
|
10: { color: '#5183A0', label: 'queued' },
|
||||||
|
20: { color: '#5183A0', label: 'processing' },
|
||||||
|
30: { color: '#44CC11', label: 'success' },
|
||||||
|
40: { color: '#F8A97D', label: 'skipped' },
|
||||||
|
50: { color: '#CEA61B', label: 'unstable' },
|
||||||
|
60: { color: '#555555', label: 'timeout' },
|
||||||
|
70: { color: '#6BAFBD', label: 'cancelled' },
|
||||||
|
80: { color: '#DC5F59', label: 'failed' },
|
||||||
|
90: { color: '#555555', label: 'stopped' },
|
||||||
|
}
|
||||||
|
|
||||||
|
const schema = Joi.array()
|
||||||
|
.items(
|
||||||
|
Joi.object({
|
||||||
|
branchName: Joi.string().required(),
|
||||||
|
statusCode: Joi.number()
|
||||||
|
.valid(Object.keys(statusCodes).map(key => parseInt(key)))
|
||||||
|
.required(),
|
||||||
|
}).required()
|
||||||
|
)
|
||||||
|
.required()
|
||||||
|
|
||||||
|
module.exports = class Shippable extends BaseJsonService {
|
||||||
|
async fetch({ projectId }) {
|
||||||
|
const url = `https://api.shippable.com/projects/${projectId}/branchRunStatus`
|
||||||
|
return this._requestJson({ schema, url })
|
||||||
|
}
|
||||||
|
|
||||||
|
static get defaultBadgeData() {
|
||||||
|
return { label: 'shippable' }
|
||||||
|
}
|
||||||
|
|
||||||
// This legacy service should be rewritten to use e.g. BaseJsonService.
|
|
||||||
//
|
|
||||||
// Tips for rewriting:
|
|
||||||
// https://github.com/badges/shields/blob/master/doc/rewriting-services.md
|
|
||||||
//
|
|
||||||
// Do not base new services on this code.
|
|
||||||
module.exports = class Shippable extends LegacyService {
|
|
||||||
static get category() {
|
static get category() {
|
||||||
return 'build'
|
return 'build'
|
||||||
}
|
}
|
||||||
@@ -18,6 +46,8 @@ module.exports = class Shippable extends LegacyService {
|
|||||||
static get route() {
|
static get route() {
|
||||||
return {
|
return {
|
||||||
base: 'shippable',
|
base: 'shippable',
|
||||||
|
format: '([^/]+)(?:/(.+))?',
|
||||||
|
capture: ['projectId', 'branch'],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,7 +57,7 @@ module.exports = class Shippable extends LegacyService {
|
|||||||
title: 'Shippable',
|
title: 'Shippable',
|
||||||
pattern: ':projectId',
|
pattern: ':projectId',
|
||||||
namedParams: { projectId: '5444c5ecb904a4b21567b0ff' },
|
namedParams: { projectId: '5444c5ecb904a4b21567b0ff' },
|
||||||
staticExample: { label: 'build', message: 'success', color: '#44CC11' },
|
staticExample: this.render({ code: 30 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Shippable branch',
|
title: 'Shippable branch',
|
||||||
@@ -36,66 +66,25 @@ module.exports = class Shippable extends LegacyService {
|
|||||||
projectId: '5444c5ecb904a4b21567b0ff',
|
projectId: '5444c5ecb904a4b21567b0ff',
|
||||||
branch: 'master',
|
branch: 'master',
|
||||||
},
|
},
|
||||||
staticExample: { label: 'build', message: 'success', color: '#44CC11' },
|
staticExample: this.render({ code: 30 }),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
static registerLegacyRouteHandler({ camp, cache }) {
|
static render({ code }) {
|
||||||
camp.route(
|
return {
|
||||||
/^\/shippable\/([^/]+)(?:\/(.+))?\.(svg|png|gif|jpg|json)$/,
|
label: 'build',
|
||||||
cache((data, match, sendBadge, request) => {
|
message: statusCodes[code].label,
|
||||||
// source: https://github.com/badges/shields/pull/1362#discussion_r161693830
|
color: statusCodes[code].color,
|
||||||
const statusCodes = {
|
}
|
||||||
0: { color: '#5183A0', label: 'waiting' },
|
}
|
||||||
10: { color: '#5183A0', label: 'queued' },
|
|
||||||
20: { color: '#5183A0', label: 'processing' },
|
|
||||||
30: { color: '#44CC11', label: 'success' },
|
|
||||||
40: { color: '#F8A97D', label: 'skipped' },
|
|
||||||
50: { color: '#CEA61B', label: 'unstable' },
|
|
||||||
60: { color: '#555555', label: 'timeout' },
|
|
||||||
70: { color: '#6BAFBD', label: 'cancelled' },
|
|
||||||
80: { color: '#DC5F59', label: 'failed' },
|
|
||||||
90: { color: '#555555', label: 'stopped' },
|
|
||||||
}
|
|
||||||
|
|
||||||
const projectId = match[1] // eg, 54d119db5ab6cc13528ab183
|
async handle({ projectId, branch = 'master' }) {
|
||||||
let targetBranch = match[2]
|
const data = await this.fetch({ projectId })
|
||||||
if (targetBranch == null) {
|
const builds = data.filter(result => result.branchName === branch)
|
||||||
targetBranch = 'master'
|
if (builds.length === 0) {
|
||||||
}
|
throw new NotFound({ prettyMessage: 'branch not found' })
|
||||||
const format = match[3]
|
}
|
||||||
const url = `https://api.shippable.com/projects/${projectId}/branchRunStatus`
|
return this.constructor.render({ code: builds[0].statusCode })
|
||||||
const options = {
|
|
||||||
method: 'GET',
|
|
||||||
uri: url,
|
|
||||||
}
|
|
||||||
|
|
||||||
const badgeData = getBadgeData('build', data)
|
|
||||||
|
|
||||||
request(options, (err, res, buffer) => {
|
|
||||||
if (checkErrorResponse(badgeData, err, res)) {
|
|
||||||
sendBadge(format, badgeData)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
res = JSON.parse(buffer)
|
|
||||||
for (const branch of res) {
|
|
||||||
if (branch.branchName === targetBranch) {
|
|
||||||
badgeData.text[1] = statusCodes[branch.statusCode].label
|
|
||||||
badgeData.colorB = statusCodes[branch.statusCode].color
|
|
||||||
sendBadge(format, badgeData)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
badgeData.text[1] = 'branch not found'
|
|
||||||
sendBadge(format, badgeData)
|
|
||||||
} catch (e) {
|
|
||||||
badgeData.text[1] = 'invalid'
|
|
||||||
sendBadge(format, badgeData)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const Joi = require('joi')
|
const Joi = require('joi')
|
||||||
const { invalidJSON } = require('../response-fixtures')
|
|
||||||
const { isBuildStatus } = require('../test-validators')
|
const { isBuildStatus } = require('../test-validators')
|
||||||
|
|
||||||
const t = (module.exports = require('../create-service-tester')())
|
const t = (module.exports = require('../create-service-tester')())
|
||||||
@@ -26,25 +25,11 @@ t.create('build status (valid, with branch)')
|
|||||||
|
|
||||||
t.create('build status (branch not found)')
|
t.create('build status (branch not found)')
|
||||||
.get('/5444c5ecb904a4b21567b0ff/not-a-branch.json')
|
.get('/5444c5ecb904a4b21567b0ff/not-a-branch.json')
|
||||||
.expectJSON({ name: 'build', value: 'branch not found' })
|
.expectJSON({ name: 'shippable', value: 'branch not found' })
|
||||||
|
|
||||||
t.create('build status (not found)')
|
t.create('build status (not found)')
|
||||||
.get('/not-a-build.json')
|
.get('/not-a-build.json')
|
||||||
.expectJSON({ name: 'build', value: 'not found' })
|
.expectJSON({ name: 'shippable', value: 'not found' })
|
||||||
|
|
||||||
t.create('build status (connection error)')
|
|
||||||
.get('/5444c5ecb904a4b21567b0ff.json')
|
|
||||||
.networkOff()
|
|
||||||
.expectJSON({ name: 'build', value: 'inaccessible' })
|
|
||||||
|
|
||||||
t.create('build status (unexpected response)')
|
|
||||||
.get('/5444c5ecb904a4b21567b0ff.json')
|
|
||||||
.intercept(nock =>
|
|
||||||
nock('https://api.shippable.com/')
|
|
||||||
.get('/projects/5444c5ecb904a4b21567b0ff/branchRunStatus')
|
|
||||||
.reply(invalidJSON)
|
|
||||||
)
|
|
||||||
.expectJSON({ name: 'build', value: 'invalid' })
|
|
||||||
|
|
||||||
t.create('build status (unexpected status code)')
|
t.create('build status (unexpected status code)')
|
||||||
.get('/5444c5ecb904a4b21567b0ff.json')
|
.get('/5444c5ecb904a4b21567b0ff.json')
|
||||||
@@ -53,4 +38,4 @@ t.create('build status (unexpected status code)')
|
|||||||
.get('/projects/5444c5ecb904a4b21567b0ff/branchRunStatus')
|
.get('/projects/5444c5ecb904a4b21567b0ff/branchRunStatus')
|
||||||
.reply(200, '[{ "branchName": "master", "statusCode": 63 }]')
|
.reply(200, '[{ "branchName": "master", "statusCode": 63 }]')
|
||||||
)
|
)
|
||||||
.expectJSON({ name: 'build', value: 'invalid' })
|
.expectJSON({ name: 'shippable', value: 'invalid response data' })
|
||||||
|
|||||||
Reference in New Issue
Block a user