diff --git a/lib/all-badge-examples.js b/lib/all-badge-examples.js index 74acbde8028bb..f96ba02805aa4 100644 --- a/lib/all-badge-examples.js +++ b/lib/all-badge-examples.js @@ -150,14 +150,6 @@ const allBadgeExamples = [ keywords: ['teamcity'], exampleUri: '/teamcity/http/teamcity.jetbrains.com/e/bt345.svg', }, - { - title: 'AppVeyor tests', - previewUri: '/appveyor/tests/NZSmartie/coap-net-iu0to.svg', - }, - { - title: 'AppVeyor tests branch', - previewUri: '/appveyor/tests/NZSmartie/coap-net-iu0to/master.svg', - }, { title: 'Buildkite', previewUri: diff --git a/server.js b/server.js index 57da0ae722c3b..1198d4b788d4a 100644 --- a/server.js +++ b/server.js @@ -647,59 +647,6 @@ cache(function (data, match, sendBadge, request) { }); })); -// AppVeyor test status integration. -camp.route(/^\/appveyor\/tests\/([^/]+\/[^/]+)(?:\/(.+))?\.(svg|png|gif|jpg|json)$/, -cache(function(data, match, sendBadge, request) { - var repo = match[1]; // eg, `gruntjs/grunt`. - var branch = match[2]; - var format = match[3]; - var apiUrl = 'https://ci.appveyor.com/api/projects/' + repo; - if (branch != null) { - apiUrl += '/branch/' + branch; - } - var badgeData = getBadgeData('tests', data); - request(apiUrl, { headers: { 'Accept': 'application/json' } }, function(err, res, buffer) { - if (err != null) { - badgeData.text[1] = 'inaccessible'; - sendBadge(format, badgeData); - return; - } - try { - if (res.statusCode === 404) { - badgeData.text[1] = 'project not found or access denied'; - sendBadge(format, badgeData); - return; - } - var data = JSON.parse(buffer); - var testsTotal = data.build.jobs.reduce((currentValue, job) => currentValue + job.testsCount, 0); - var testsPassed = data.build.jobs.reduce((currentValue, job) => currentValue + job.passedTestsCount, 0); - var testsFailed = data.build.jobs.reduce((currentValue, job) => currentValue + job.failedTestsCount, 0); - var testsSkipped = testsTotal - testsPassed - testsFailed; - - if (testsPassed == testsTotal) { - badgeData.colorscheme = 'brightgreen'; - } else if (testsFailed == 0 ) { - badgeData.colorscheme = 'green'; - } else if (testsPassed == 0 ) { - badgeData.colorscheme = 'red'; - } else{ - badgeData.colorscheme = 'orange'; - } - - badgeData.text[1] = testsPassed + ' passed'; - if (testsFailed > 0) - badgeData.text[1] += ', ' + testsFailed + ' failed'; - if (testsSkipped > 0) - badgeData.text[1] += ', ' + testsSkipped + ' skipped'; - - sendBadge(format, badgeData); - } catch(e) { - badgeData.text[1] = 'invalid'; - sendBadge(format, badgeData); - } - }); -})); - // Old url for CodeBetter TeamCity instance. camp.route(/^\/teamcity\/codebetter\/(.*)\.(svg|png|gif|jpg|json)$/, cache(function(data, match, sendBadge, request) { diff --git a/services/appveyor/appveyor-base.js b/services/appveyor/appveyor-base.js new file mode 100644 index 0000000000000..eaa75c049a130 --- /dev/null +++ b/services/appveyor/appveyor-base.js @@ -0,0 +1,44 @@ +'use strict' + +const Joi = require('joi') +const BaseJsonService = require('../base-json') +const { nonNegativeInteger } = require('../validators') + +const schema = Joi.object({ + build: Joi.object({ + status: Joi.string().required(), + jobs: Joi.array() + .items({ + testsCount: nonNegativeInteger, + passedTestsCount: nonNegativeInteger, + failedTestsCount: nonNegativeInteger, + }) + .required(), + }), +}).required() + +module.exports = class AppVeyorBase extends BaseJsonService { + static get category() { + return 'build' + } + + async fetch({ repo, branch }) { + let url = `https://ci.appveyor.com/api/projects/${repo}` + if (branch != null) { + url += `/branch/${branch}` + } + return this._requestJson({ + schema, + url, + errorMessages: { 404: 'project not found or access denied' }, + }) + } + + static buildUrl(base) { + return { + base, + format: '([^/]+/[^/]+)(?:/(.+))?', + capture: ['repo', 'branch'], + } + } +} diff --git a/services/appveyor/appveyor-ci.service.js b/services/appveyor/appveyor-ci.service.js new file mode 100644 index 0000000000000..e377732d2638d --- /dev/null +++ b/services/appveyor/appveyor-ci.service.js @@ -0,0 +1,39 @@ +'use strict' + +const AppVeyorBase = require('./appveyor-base') + +module.exports = class AppVeyorCi extends AppVeyorBase { + static get url() { + return this.buildUrl('appveyor/ci') + } + + static get examples() { + return [ + { + title: 'AppVeyor', + previewUrl: 'gruntjs/grunt', + }, + { + title: 'AppVeyor branch', + previewUrl: 'gruntjs/grunt/master', + }, + ] + } + + static render({ status }) { + if (status === 'success') { + return { message: 'passing', color: 'brightgreen' } + } else if (status !== 'running' && status !== 'queued') { + return { message: 'failing', color: 'red' } + } else { + return { message: status } + } + } + + async handle({ repo, branch }) { + const { + build: { status }, + } = await this.fetch({ repo, branch }) + return this.constructor.render({ status }) + } +} diff --git a/services/appveyor/appveyor-tests.service.js b/services/appveyor/appveyor-tests.service.js new file mode 100644 index 0000000000000..03851fbfba3a7 --- /dev/null +++ b/services/appveyor/appveyor-tests.service.js @@ -0,0 +1,69 @@ +'use strict' + +const AppVeyorBase = require('./appveyor-base') + +module.exports = class AppVeyorTests extends AppVeyorBase { + static get url() { + return this.buildUrl('appveyor/tests') + } + + static get defaultBadgeData() { + return { + label: 'tests', + } + } + + static get examples() { + return [ + { + title: 'AppVeyor tests', + previewUrl: 'NZSmartie/coap-net-iu0to', + }, + { + title: 'AppVeyor tests branch', + previewUrl: 'NZSmartie/coap-net-iu0to/master', + }, + ] + } + + static render({ passed, failed, skipped, total }) { + let message = `${passed} passed` + if (failed > 0) { + message += `, ${failed} failed` + } + if (skipped > 0) { + message += `, ${skipped} skipped` + } + + let color + if (passed === total) { + color = 'brightgreen' + } else if (failed === 0) { + color = 'green' + } else if (passed === 0) { + color = 'red' + } else { + color = 'orange' + } + + return { message, color } + } + + async handle({ repo, branch }) { + const { + build: { jobs }, + } = await this.fetch({ repo, branch }) + + let total = 0, + passed = 0, + failed = 0 + jobs.forEach(job => { + total += job.testsCount + passed += job.passedTestsCount + failed += job.failedTestsCount + }) + const skipped = total - passed - failed + + return this.constructor.render({ passed, failed, skipped, total }) + } +} diff --git a/services/appveyor/appveyor.service.js b/services/appveyor/appveyor.service.js deleted file mode 100644 index 6490d53e92627..0000000000000 --- a/services/appveyor/appveyor.service.js +++ /dev/null @@ -1,66 +0,0 @@ -'use strict' - -const Joi = require('joi') -const BaseJsonService = require('../base-json') - -const appVeyorSchema = Joi.object({ - build: Joi.object({ - status: Joi.string().required(), - }), -}).required() - -module.exports = class AppVeyor extends BaseJsonService { - async fetch({ repo, branch }) { - let url = `https://ci.appveyor.com/api/projects/${repo}` - if (branch != null) { - url += `/branch/${branch}` - } - return this._requestJson({ - schema: appVeyorSchema, - url, - errorMessages: { 404: 'project not found or access denied' }, - }) - } - - static render({ status }) { - if (status === 'success') { - return { message: 'passing', color: 'brightgreen' } - } else if (status !== 'running' && status !== 'queued') { - return { message: 'failing', color: 'red' } - } else { - return { message: status } - } - } - - async handle({ repo, branch }) { - const { - build: { status }, - } = await this.fetch({ repo, branch }) - return this.constructor.render({ status }) - } - - // Metadata - static get category() { - return 'build' - } - - static get url() { - return { - base: 'appveyor/ci', - format: '([^/]+/[^/]+)(?:/(.+))?', - capture: ['repo', 'branch'], - } - } - - static get examples() { - return [ - { - previewUrl: 'gruntjs/grunt', - }, - { - title: `${this.name} branch`, - previewUrl: 'gruntjs/grunt/master', - }, - ] - } -}