refactor [circleci] integration (#1927)
* refactor [circleci] integration
This commit is contained in:
@@ -167,24 +167,6 @@ const allBadgeExamples = [
|
||||
title: 'Codeship',
|
||||
previewUri: '/codeship/d6c1ddd0-16a3-0132-5f85-2e35c05e22b1/master.svg',
|
||||
},
|
||||
{
|
||||
title: 'CircleCI',
|
||||
previewUri: '/circleci/project/github/RedSparr0w/node-csgo-parser.svg',
|
||||
},
|
||||
{
|
||||
title: 'CircleCI branch',
|
||||
previewUri:
|
||||
'/circleci/project/github/RedSparr0w/node-csgo-parser/master.svg',
|
||||
},
|
||||
{
|
||||
title: 'CircleCI token',
|
||||
previewUri:
|
||||
'/circleci/project/github/RedSparr0w/node-csgo-parser/master.svg',
|
||||
urlPattern:
|
||||
'/circleci/token/:token/project/github/RedSparr0w/node-csgo-parser/master.svg',
|
||||
exampleUri:
|
||||
'/circleci/token/b90b5c49e59a4c67ba3a92f7992587ac7a0408c2/project/github/RedSparr0w/node-csgo-parser/master.svg',
|
||||
},
|
||||
{
|
||||
title: 'Visual Studio Team services',
|
||||
previewUri:
|
||||
|
||||
80
server.js
80
server.js
@@ -3,7 +3,6 @@
|
||||
const dom = require('xmldom').DOMParser;
|
||||
const jp = require('jsonpath');
|
||||
const path = require('path');
|
||||
const queryString = require('query-string');
|
||||
const xpath = require('xpath');
|
||||
const yaml = require('js-yaml');
|
||||
const Raven = require('raven');
|
||||
@@ -118,85 +117,6 @@ loadServiceClasses().forEach(
|
||||
{ camp, handleRequest: cache, githubApiProvider },
|
||||
{ handleInternalErrors: config.handleInternalErrors }));
|
||||
|
||||
// CircleCI build integration.
|
||||
// https://circleci.com/api/v1/project/BrightFlair/PHP.Gt?circle-token=0a5143728784b263d9f0238b8d595522689b3af2&limit=1&filter=completed
|
||||
camp.route(/^\/circleci\/(?:token\/(\w+))?[+/]?project\/(?:(github|bitbucket)\/)?([^/]+\/[^/]+)(?:\/(.*))?\.(svg|png|gif|jpg|json)$/,
|
||||
cache(function(data, match, sendBadge, request) {
|
||||
const token = match[1];
|
||||
const type = match[2] || 'github'; // github OR bitbucket
|
||||
const userRepo = match[3]; // eg, `RedSparr0w/node-csgo-parser`.
|
||||
const branch = match[4];
|
||||
const format = match[5];
|
||||
|
||||
// Base API URL
|
||||
let apiUrl = 'https://circleci.com/api/v1.1/project/' + type + '/' + userRepo;
|
||||
|
||||
// Query Params
|
||||
var queryParams = {};
|
||||
queryParams['limit'] = 1;
|
||||
queryParams['filter'] = 'completed';
|
||||
|
||||
// Custom Banch if present
|
||||
if (branch != null) {
|
||||
apiUrl += "/tree/" + branch;
|
||||
}
|
||||
|
||||
// Append Token to Query Params if present
|
||||
if (token) {
|
||||
queryParams['circle-token'] = token;
|
||||
}
|
||||
|
||||
// Apprend query params to API URL
|
||||
apiUrl += '?' + queryString.stringify(queryParams);
|
||||
|
||||
const badgeData = getBadgeData('build', data);
|
||||
request(apiUrl, { json:true }, function(err, res, data) {
|
||||
if (checkErrorResponse(badgeData, err, res, { 404: 'project not found' })) {
|
||||
sendBadge(format, badgeData);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (data.message !== undefined){
|
||||
badgeData.text[1] = data.message;
|
||||
sendBadge(format, badgeData);
|
||||
return;
|
||||
}
|
||||
|
||||
let passCount = 0;
|
||||
let status;
|
||||
for (let i=0; i<data.length; i++) {
|
||||
status = data[i].status;
|
||||
if (['success', 'fixed'].includes(status)) {
|
||||
passCount++;
|
||||
} else if (status === 'failed') {
|
||||
badgeData.colorscheme = 'red';
|
||||
badgeData.text[1] = 'failed';
|
||||
sendBadge(format, badgeData);
|
||||
return;
|
||||
} else if (['no_tests', 'scheduled', 'not_run'].includes(status)) {
|
||||
badgeData.colorscheme = 'yellow';
|
||||
badgeData.text[1] = status.replace('_', ' ');
|
||||
sendBadge(format, badgeData);
|
||||
return;
|
||||
} else {
|
||||
badgeData.text[1] = status.replace('_', ' ');
|
||||
sendBadge(format, badgeData);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (passCount === data.length) {
|
||||
badgeData.colorscheme = 'brightgreen';
|
||||
badgeData.text[1] = 'passing';
|
||||
}
|
||||
sendBadge(format, badgeData);
|
||||
} catch(e) {
|
||||
badgeData.text[1] = 'invalid';
|
||||
sendBadge(format, badgeData);
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
// User defined sources - JSON response
|
||||
camp.route(/^\/badge\/dynamic\/(json|xml|yaml)\.(svg|png|gif|jpg|json)$/,
|
||||
cache({
|
||||
|
||||
89
services/circleci/circleci.service.js
Normal file
89
services/circleci/circleci.service.js
Normal file
@@ -0,0 +1,89 @@
|
||||
'use strict'
|
||||
|
||||
const Joi = require('joi')
|
||||
const BaseJsonService = require('../base-json')
|
||||
|
||||
const circleSchema = Joi.array()
|
||||
.items(Joi.object({ status: Joi.string().required() }))
|
||||
.min(1)
|
||||
.max(1)
|
||||
.required()
|
||||
|
||||
module.exports = class CircleCi extends BaseJsonService {
|
||||
async fetch({ token, vcsType, userRepo, branch }) {
|
||||
let url = `https://circleci.com/api/v1.1/project/${vcsType}/${userRepo}`
|
||||
if (branch != null) {
|
||||
url += `/tree/${branch}`
|
||||
}
|
||||
const query = { filter: 'completed', limit: 1 }
|
||||
if (token) {
|
||||
query['circle-token'] = token
|
||||
}
|
||||
return this._requestJson({
|
||||
url,
|
||||
schema: circleSchema,
|
||||
options: { qs: query },
|
||||
errorMessages: { 404: 'project not found' },
|
||||
})
|
||||
}
|
||||
|
||||
static render({ status }) {
|
||||
if (['success', 'fixed'].includes(status)) {
|
||||
return { message: 'passing', color: 'brightgreen' }
|
||||
} else if (status === 'failed') {
|
||||
return { message: 'failed', color: 'red' }
|
||||
} else if (['no_tests', 'scheduled', 'not_run'].includes(status)) {
|
||||
return { message: status.replace('_', ' '), color: 'yellow' }
|
||||
} else {
|
||||
return { message: status.replace('_', ' '), color: 'lightgrey' }
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ token, vcsType, userRepo, branch }) {
|
||||
const json = await this.fetch({ token, vcsType, userRepo, branch })
|
||||
return this.constructor.render({ status: json[0].status })
|
||||
}
|
||||
|
||||
// Metadata
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'build' }
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'build'
|
||||
}
|
||||
|
||||
static get url() {
|
||||
return {
|
||||
base: 'circleci',
|
||||
format:
|
||||
'(?:token/(w+))?[+/]?project/(?:(github|bitbucket)/)?([^/]+/[^/]+)(?:/(.*))?',
|
||||
capture: ['token', 'vcsType', 'userRepo', 'branch'],
|
||||
}
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
title: 'CircleCI (all branches)',
|
||||
exampleUrl: 'project/github/RedSparr0w/node-csgo-parser',
|
||||
urlPattern: 'project/:vcsType/:owner/:repo',
|
||||
staticExample: this.render({ status: 'success' }),
|
||||
},
|
||||
{
|
||||
title: 'CircleCI branch',
|
||||
exampleUrl: 'project/github/RedSparr0w/node-csgo-parser/master',
|
||||
urlPattern: 'project/:vcsType/:owner/:repo/:branch',
|
||||
staticExample: this.render({ status: 'success' }),
|
||||
},
|
||||
{
|
||||
title: 'CircleCI token',
|
||||
urlPattern:
|
||||
'circleci/token/:token/project/:vcsType/:owner/:repo/:branch',
|
||||
exampleUrl:
|
||||
'circleci/token/b90b5c49e59a4c67ba3a92f7992587ac7a0408c2/project/github/RedSparr0w/node-csgo-parser/master',
|
||||
staticExample: this.render({ status: 'success' }),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
const Joi = require('joi')
|
||||
const ServiceTester = require('../service-tester')
|
||||
const { invalidJSON } = require('../response-fixtures')
|
||||
const { isBuildStatus } = require('../test-validators')
|
||||
|
||||
const t = new ServiceTester({ id: 'circleci', title: 'Circle CI' })
|
||||
@@ -35,17 +34,6 @@ t.create('circle ci (connection error)')
|
||||
.networkOff()
|
||||
.expectJSON({ name: 'build', value: 'inaccessible' })
|
||||
|
||||
t.create('circle ci (unexpected response)')
|
||||
.get('/project/github/RedSparr0w/node-csgo-parser.json')
|
||||
.intercept(nock =>
|
||||
nock('https://circleci.com')
|
||||
.get(
|
||||
'/api/v1.1/project/github/RedSparr0w/node-csgo-parser?filter=completed&limit=1'
|
||||
)
|
||||
.reply(invalidJSON)
|
||||
)
|
||||
.expectJSON({ name: 'build', value: 'invalid' })
|
||||
|
||||
t.create('circle ci (no response data)')
|
||||
.get('/project/github/RedSparr0w/node-csgo-parser.json')
|
||||
.intercept(nock =>
|
||||
@@ -55,9 +43,10 @@ t.create('circle ci (no response data)')
|
||||
)
|
||||
.reply(200)
|
||||
)
|
||||
.expectJSON({ name: 'build', value: 'invalid' })
|
||||
.expectJSON({ name: 'build', value: 'unparseable json response' })
|
||||
|
||||
t.create('circle ci (multiple pipelines, pass)')
|
||||
// we're passing &limit=1 so we expect exactly one array element
|
||||
t.create('circle ci (invalid json)')
|
||||
.get('/project/github/RedSparr0w/node-csgo-parser.json?style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://circleci.com')
|
||||
@@ -66,15 +55,8 @@ t.create('circle ci (multiple pipelines, pass)')
|
||||
)
|
||||
.reply(200, [{ status: 'success' }, { status: 'fixed' }])
|
||||
)
|
||||
.expectJSON({ name: 'build', value: 'passing', colorB: '#4c1' })
|
||||
|
||||
t.create('circle ci (multiple pipelines, fail)')
|
||||
.get('/project/github/RedSparr0w/node-csgo-parser.json?style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://circleci.com')
|
||||
.get(
|
||||
'/api/v1.1/project/github/RedSparr0w/node-csgo-parser?filter=completed&limit=1'
|
||||
)
|
||||
.reply(200, [{ status: 'success' }, { status: 'failed' }])
|
||||
)
|
||||
.expectJSON({ name: 'build', value: 'failed', colorB: '#e05d44' })
|
||||
.expectJSON({
|
||||
name: 'build',
|
||||
value: 'invalid json response',
|
||||
colorB: '#9f9f9f',
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user