Skip to content

Commit

Permalink
Merge pull request #286 from aaricpittman/vulnerability-alerts
Browse files Browse the repository at this point in the history
  • Loading branch information
travi committed Nov 19, 2020
2 parents c4eae24 + 44365d6 commit 20e72fb
Show file tree
Hide file tree
Showing 7 changed files with 237 additions and 21 deletions.
8 changes: 8 additions & 0 deletions README.md
Expand Up @@ -61,6 +61,14 @@ repository:
# rebase-merging.
allow_rebase_merge: true

# Either `true` to enable automated security fixes, or `false` to disable
# automated security fixes.
enable_automated_security_fixes: true

# Either `true` to enable vulnerability alerts, or `false` to disable
# vulnerability alerts.
enable_vulnerability_alerts: true

# Labels: define labels for Issues and Pull Requests
labels:
- name: bug
Expand Down
67 changes: 55 additions & 12 deletions lib/plugins/repository.js
@@ -1,24 +1,67 @@
const enableAutomatedSecurityFixes = ({ github, settings, enabled }) => {
if (enabled === undefined) {
return Promise.resolve()
}

const args = {
owner: settings.owner,
repo: settings.repo,
mediaType: {
previews: ['london']
}
}
const methodName = enabled ? 'enableAutomatedSecurityFixes' : 'disableAutomatedSecurityFixes'

return github.repos[methodName](args)
}

const enableVulnerabilityAlerts = ({ github, settings, enabled }) => {
if (enabled === undefined) {
return Promise.resolve()
}

const args = {
owner: settings.owner,
repo: settings.repo,
mediaType: {
previews: ['dorian']
}
}
const methodName = enabled ? 'enableVulnerabilityAlerts' : 'disableVulnerabilityAlerts'

return github.repos[methodName](args)
}

module.exports = class Repository {
constructor (github, repo, settings) {
this.github = github
this.settings = Object.assign({ mediaType: { previews: ['baptiste'] } }, settings, repo)
this.topics = this.settings.topics
delete this.settings.topics

this.enableVulnerabilityAlerts = this.settings.enable_vulnerability_alerts
delete this.settings.enable_vulnerability_alerts

this.enableAutomatedSecurityFixes = this.settings.enable_automated_security_fixes
delete this.settings.enable_automated_security_fixes
}

sync () {
this.settings.name = this.settings.name || this.settings.repo
return this.github.repos.update(this.settings).then(() => {
if (this.topics) {
return this.github.repos.replaceTopics({
owner: this.settings.owner,
repo: this.settings.repo,
names: this.topics.split(/\s*,\s*/),
mediaType: {
previews: ['mercy']
}
})
}
})
return this.github.repos.update(this.settings)
.then(() => {
if (this.topics) {
return this.github.repos.replaceTopics({
owner: this.settings.owner,
repo: this.settings.repo,
names: this.topics.split(/\s*,\s*/),
mediaType: {
previews: ['mercy']
}
})
}
})
.then(() => enableVulnerabilityAlerts({ enabled: this.enableVulnerabilityAlerts, ...this }))
.then(() => enableAutomatedSecurityFixes({ enabled: this.enableAutomatedSecurityFixes, ...this }))
}
}
5 changes: 5 additions & 0 deletions test/fixtures/repository/basic-config-with-security-fixes.yml
@@ -0,0 +1,5 @@
repository:
name: bar
delete_branch_on_merge: true
is_template: true
enable_automated_security_fixes: true
@@ -0,0 +1,5 @@
repository:
name: bar
delete_branch_on_merge: true
is_template: true
enable_vulnerability_alerts: true
File renamed without changes.
67 changes: 59 additions & 8 deletions test/integration/plugins/repository.test.js
@@ -1,9 +1,15 @@
const path = require('path')
const fs = require('fs')
const yaml = require('js-yaml')
const settings = require('../../../lib/settings')
const { buildTriggerEvent, initializeNock, loadInstance, repository, teardownNock } = require('../common')

const loadConfig = (configFilename) => {
const pathToConfig = path.resolve(__dirname, '..', '..', 'fixtures', 'repository', configFilename)
const configFile = Buffer.from(fs.readFileSync(pathToConfig, 'utf8'))

return configFile.toString()
}

describe('repository plugin', function () {
let probot, githubScope

Expand All @@ -16,22 +22,67 @@ describe('repository plugin', function () {
teardownNock(githubScope)
})

it('syncs repo settings', async () => {
const pathToConfig = path.resolve(__dirname, '..', '..', 'fixtures', 'repository-config.yml')
const configFile = Buffer.from(fs.readFileSync(pathToConfig, 'utf8'))
const config = yaml.safeLoad(configFile, 'utf8')
const configContent = configFile.toString()
it('syncs repo with basic settings', async () => {
const config = loadConfig('basic-config.yml')
const repoSettings = Object.assign({}, config.repository)

githubScope
.get(`/repos/${repository.owner.name}/${repository.name}/contents/${encodeURIComponent(settings.FILE_NAME)}`)
.reply(200, configContent)
.reply(200, config)
githubScope
.patch(`/repos/${repository.owner.name}/${repository.name}`, body => {
expect(body).toMatchObject(config.repository)
expect(body).toMatchObject(repoSettings)
return true
})
.matchHeader('accept', ['application/vnd.github.baptiste-preview+json'])
.reply(200)

await probot.receive(buildTriggerEvent())
})

it('syncs repo with basic settings and vulnerability alerts enabled', async () => {
const config = loadConfig('basic-config-with-vulnerability-alerts.yml')
const repoSettings = Object.assign({}, config.repository)
delete repoSettings.enable_vulnerability_alerts

githubScope
.get(`/repos/${repository.owner.name}/${repository.name}/contents/${encodeURIComponent(settings.FILE_NAME)}`)
.reply(200, config)
githubScope
.patch(`/repos/${repository.owner.name}/${repository.name}`, body => {
expect(body).toMatchObject(repoSettings)
return true
})
.matchHeader('accept', ['application/vnd.github.baptiste-preview+json'])
.reply(200)
githubScope
.put(`/repos/${repository.owner.name}/${repository.name}/vulnerability-alerts`, body => true)
.matchHeader('accept', ['application/vnd.github.dorian-preview+json'])
.reply(200)

await probot.receive(buildTriggerEvent())
})

it('syncs repo with basic settings and security fixes enabled', async () => {
const config = loadConfig('basic-config-with-security-fixes.yml')
const repoSettings = Object.assign({}, config.repository)
delete repoSettings.enable_automated_security_fixes

githubScope
.get(`/repos/${repository.owner.name}/${repository.name}/contents/${encodeURIComponent(settings.FILE_NAME)}`)
.reply(200, config)
githubScope
.patch(`/repos/${repository.owner.name}/${repository.name}`, body => {
expect(body).toMatchObject(repoSettings)
return true
})
.matchHeader('accept', ['application/vnd.github.baptiste-preview+json'])
.reply(200)
githubScope
.put(`/repos/${repository.owner.name}/${repository.name}/automated-security-fixes`, body => true)
.matchHeader('accept', ['application/vnd.github.london-preview+json'])
.reply(200)

await probot.receive(buildTriggerEvent())
})
})
106 changes: 105 additions & 1 deletion test/unit/lib/plugins/repository.test.js
Expand Up @@ -12,7 +12,11 @@ describe('Repository', () => {
repos: {
get: jest.fn().mockImplementation(() => Promise.resolve({})),
update: jest.fn().mockImplementation(() => Promise.resolve()),
replaceTopics: jest.fn().mockImplementation(() => Promise.resolve())
replaceTopics: jest.fn().mockImplementation(() => Promise.resolve()),
enableVulnerabilityAlerts: jest.fn().mockImplementation(() => Promise.resolve()),
disableVulnerabilityAlerts: jest.fn().mockImplementation(() => Promise.resolve()),
enableAutomatedSecurityFixes: jest.fn().mockImplementation(() => Promise.resolve()),
disableAutomatedSecurityFixes: jest.fn().mockImplementation(() => Promise.resolve())
}
}
})
Expand Down Expand Up @@ -64,5 +68,105 @@ describe('Repository', () => {
})
})
})

describe('vulnerability alerts', () => {
it('it skips if not set', () => {
const plugin = configure({
enable_vulnerability_alerts: undefined
})

return plugin.sync().then(() => {
expect(github.repos.enableVulnerabilityAlerts).not.toHaveBeenCalledWith({
owner: 'bkeepers',
repo: 'test',
mediaType: {
previews: ['dorian']
}
})
})
})

it('enables vulerability alerts when set to true', () => {
const plugin = configure({
enable_vulnerability_alerts: true
})

return plugin.sync().then(() => {
expect(github.repos.enableVulnerabilityAlerts).toHaveBeenCalledWith({
owner: 'bkeepers',
repo: 'test',
mediaType: {
previews: ['dorian']
}
})
})
})

it('disables vulerability alerts when set to false', () => {
const plugin = configure({
enable_vulnerability_alerts: false
})

return plugin.sync().then(() => {
expect(github.repos.disableVulnerabilityAlerts).toHaveBeenCalledWith({
owner: 'bkeepers',
repo: 'test',
mediaType: {
previews: ['dorian']
}
})
})
})
})

describe('automated security fixes', () => {
it('it skips if not set', () => {
const plugin = configure({
enable_automated_security_fixes: undefined
})

return plugin.sync().then(() => {
expect(github.repos.enableAutomatedSecurityFixes).not.toHaveBeenCalledWith({
owner: 'bkeepers',
repo: 'test',
mediaType: {
previews: ['london']
}
})
})
})

it('enables vulerability alerts when set to true', () => {
const plugin = configure({
enable_automated_security_fixes: true
})

return plugin.sync().then(() => {
expect(github.repos.enableAutomatedSecurityFixes).toHaveBeenCalledWith({
owner: 'bkeepers',
repo: 'test',
mediaType: {
previews: ['london']
}
})
})
})

it('disables vulerability alerts when set to false', () => {
const plugin = configure({
enable_automated_security_fixes: false
})

return plugin.sync().then(() => {
expect(github.repos.disableAutomatedSecurityFixes).toHaveBeenCalledWith({
owner: 'bkeepers',
repo: 'test',
mediaType: {
previews: ['london']
}
})
})
})
})
})
})

0 comments on commit 20e72fb

Please sign in to comment.