* Add GitHub Deployments badge (#4477) * require a message Co-authored-by: chris48s <chris48s@users.noreply.github.com> Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
This commit is contained in:
committed by
repo-ranger[bot]
parent
e01712da76
commit
453821c40e
138
services/github/github-deployments.service.js
Normal file
138
services/github/github-deployments.service.js
Normal file
@@ -0,0 +1,138 @@
|
||||
'use strict'
|
||||
|
||||
const gql = require('graphql-tag')
|
||||
const Joi = require('@hapi/joi')
|
||||
const { GithubAuthV4Service } = require('./github-auth-service')
|
||||
const { documentation, transformErrors } = require('./github-helpers')
|
||||
const { NotFound } = require('..')
|
||||
|
||||
const greenStates = ['SUCCESS']
|
||||
const redStates = ['ERROR', 'FAILURE']
|
||||
const blueStates = ['INACTIVE']
|
||||
const otherStates = ['IN_PROGRESS', 'QUEUED', 'PENDING']
|
||||
|
||||
const allState = greenStates
|
||||
.concat(redStates)
|
||||
.concat(blueStates)
|
||||
.concat(otherStates)
|
||||
|
||||
const isDeploymentState = Joi.equal(...allState)
|
||||
|
||||
const schema = Joi.object({
|
||||
data: Joi.object({
|
||||
repository: Joi.object({
|
||||
deployments: Joi.object({
|
||||
nodes: Joi.array()
|
||||
.items(
|
||||
Joi.object({
|
||||
latestStatus: Joi.alternatives([
|
||||
Joi.object({
|
||||
state: isDeploymentState,
|
||||
}),
|
||||
null,
|
||||
]),
|
||||
})
|
||||
)
|
||||
.required(),
|
||||
}).required(),
|
||||
}).required(),
|
||||
}).required(),
|
||||
}).required()
|
||||
|
||||
module.exports = class GithubDeployments extends GithubAuthV4Service {
|
||||
static get category() {
|
||||
return 'other'
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'github/deployments',
|
||||
pattern: ':user/:repo/:environment',
|
||||
}
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
title: 'GitHub deployments',
|
||||
namedParams: {
|
||||
user: 'badges',
|
||||
repo: 'shields',
|
||||
environment: 'shields-staging',
|
||||
},
|
||||
staticPreview: this.render({
|
||||
state: 'success',
|
||||
}),
|
||||
documentation,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'state' }
|
||||
}
|
||||
|
||||
static render({ state }) {
|
||||
let color
|
||||
if (greenStates.includes(state)) {
|
||||
color = 'brightgreen'
|
||||
} else if (redStates.includes(state)) {
|
||||
color = 'red'
|
||||
} else if (blueStates.includes(state)) {
|
||||
color = 'blue'
|
||||
}
|
||||
|
||||
let message
|
||||
if (state == 'IN_PROGRESS') {
|
||||
message = 'in progress'
|
||||
} else {
|
||||
message = state.toLowerCase()
|
||||
}
|
||||
|
||||
return {
|
||||
message,
|
||||
color,
|
||||
}
|
||||
}
|
||||
|
||||
async fetch({ user, repo, environment }) {
|
||||
return await this._requestGraphql({
|
||||
query: gql`
|
||||
query($user: String!, $repo: String!, $environment: String!) {
|
||||
repository(owner: $user, name: $repo) {
|
||||
deployments(last: 1, environments: [$environment]) {
|
||||
nodes {
|
||||
latestStatus {
|
||||
state
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: { user, repo, environment },
|
||||
schema,
|
||||
transformErrors,
|
||||
})
|
||||
}
|
||||
|
||||
transform({ data }) {
|
||||
if (data.repository.deployments.nodes.length == 0) {
|
||||
throw new NotFound({ prettyMessage: 'environment not found' })
|
||||
}
|
||||
// This happens for the brief moment a deployment is created, but no
|
||||
// status is created for the deployment (yet).
|
||||
if (data.repository.deployments.nodes[0].latestStatus == null) {
|
||||
throw new NotFound({ prettyMessage: 'deployment has no status (yet)' })
|
||||
}
|
||||
|
||||
const state = data.repository.deployments.nodes[0].latestStatus.state
|
||||
return { state }
|
||||
}
|
||||
|
||||
async handle({ user, repo, environment }, queryParams) {
|
||||
const json = await this.fetch({ user, repo, environment })
|
||||
const { state } = this.transform({ data: json.data })
|
||||
return this.constructor.render({ state })
|
||||
}
|
||||
}
|
||||
69
services/github/github-deployments.spec.js
Normal file
69
services/github/github-deployments.spec.js
Normal file
@@ -0,0 +1,69 @@
|
||||
'use strict'
|
||||
|
||||
const { test, given } = require('sazerac')
|
||||
const GithubDeployments = require('./github-deployments.service')
|
||||
|
||||
describe('GithubDeployments', function() {
|
||||
test(GithubDeployments.render, () => {
|
||||
given({
|
||||
state: 'SUCCESS',
|
||||
}).expect({
|
||||
message: 'success',
|
||||
color: 'brightgreen',
|
||||
})
|
||||
given({
|
||||
state: 'ERROR',
|
||||
}).expect({
|
||||
message: 'error',
|
||||
color: 'red',
|
||||
})
|
||||
given({
|
||||
state: 'IN_PROGRESS',
|
||||
}).expect({
|
||||
message: 'in progress',
|
||||
color: undefined,
|
||||
})
|
||||
})
|
||||
|
||||
test(GithubDeployments.prototype.transform, () => {
|
||||
given({
|
||||
data: {
|
||||
repository: {
|
||||
deployments: {
|
||||
nodes: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
}).expectError('Not Found: environment not found')
|
||||
given({
|
||||
data: {
|
||||
repository: {
|
||||
deployments: {
|
||||
nodes: [
|
||||
{
|
||||
latestStatus: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
}).expectError('Not Found: deployment has no status (yet)')
|
||||
given({
|
||||
data: {
|
||||
repository: {
|
||||
deployments: {
|
||||
nodes: [
|
||||
{
|
||||
latestStatus: {
|
||||
state: 'SUCCESS',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
}).expect({
|
||||
state: 'SUCCESS',
|
||||
})
|
||||
})
|
||||
})
|
||||
29
services/github/github-deployments.tester.js
Normal file
29
services/github/github-deployments.tester.js
Normal file
@@ -0,0 +1,29 @@
|
||||
'use strict'
|
||||
|
||||
const Joi = require('@hapi/joi')
|
||||
const t = (module.exports = require('../tester').createServiceTester())
|
||||
|
||||
const validMessages = [
|
||||
'success',
|
||||
'error',
|
||||
'failure',
|
||||
'inactive',
|
||||
'in progress',
|
||||
'queued',
|
||||
'pending',
|
||||
]
|
||||
const isValidMessages = Joi.equal(...validMessages).required()
|
||||
|
||||
t.create('Deployments')
|
||||
.get('/badges/shields/shields-staging.json')
|
||||
.expectBadge({
|
||||
label: 'state',
|
||||
message: isValidMessages,
|
||||
})
|
||||
|
||||
t.create('Deployments (environment not found)')
|
||||
.get('/badges/shields/does-not-exist.json')
|
||||
.expectBadge({
|
||||
label: 'state',
|
||||
message: 'environment not found',
|
||||
})
|
||||
Reference in New Issue
Block a user