Skip to content

Commit

Permalink
Merge pull request #28 from jeramysoucy/removes-imageTag-improves-errors
Browse files Browse the repository at this point in the history
Fixes issue description and octokit pagination
  • Loading branch information
jeramysoucy authored Dec 28, 2023
2 parents 67643a7 + 84910b9 commit ad3e2b6
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 56 deletions.
27 changes: 18 additions & 9 deletions lib/github/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const chalk = require('chalk')
const getBatchIssue = require('./batch')
const { conf } = require('../config')
const { getProjectName, getGraph } = require('./utils')
const { dressError } = require('../utils')

const { getLabels, ensureLabelsAreCreated } = require('./labels')

Expand All @@ -22,19 +23,27 @@ module.exports = {

// retrieve issue IDs already created in GitHub
async existingIssues () {
return await octokit.paginate(
`GET /search/issues?q=repo%3A${conf.ghOwner}/${conf.ghRepo}+is%3Aissue+label%3Asnyk`,
(response) =>
response.data.map((existingIssue) => [
existingIssue.title,
existingIssue.number
])
)
try {
return await octokit.paginate(
`GET /search/issues?q=repo%3A${conf.ghOwner}/${conf.ghRepo}+is%3Aissue+label%3Asnyk`,
(response) =>
response.data.map((existingIssue) => [
existingIssue.title,
existingIssue.number
])
)
} catch (err) {
throw new Error(dressError(err, `Failed to paginate octokit request for existing issues in repository ${conf.ghRepo}`))
}
},

async createIssue (options) {
if (conf.dryRun) return
return await this.client.issues.create(options)
try {
return await this.client.issues.create(options)
} catch (err) {
throw new Error(dressError(err, `Failed to ${options.issue_number ? 'update' : 'create'} issue: ${options.issue_number ? options.issue_number : options.title}`))
}
},

async createIssues (issues, existingIssues) {
Expand Down
44 changes: 24 additions & 20 deletions lib/github/labels.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict'

const { conf } = require('../config')
const { uniq } = require('../utils')
const { uniq, dressError } = require('../utils')

const LABELS = {
snyk: {
Expand Down Expand Up @@ -50,32 +50,36 @@ const getLabelAttributes = (name) => {

const ensureLabelsAreCreated = async (octokit, client, ghOwner, ghRepo, issues) => {
const labels = getLabels(issues)
const responseData = await octokit.paginate(
await client.issues.listLabelsForRepo({
owner: ghOwner,
repo: ghRepo,
per_page: 100
}),
(response) => response.data
)

let responseData
try {
responseData = await octokit.paginate(`GET /repos/${conf.ghOwner}/${conf.ghRepo}/labels?per_page=100`)
} catch (err) {
throw new Error(dressError(err, `Failed to paginate octokit request for labels in repository: ${ghRepo}`))
}

const currentLabels = responseData.map((x) => x.name)
const labelsToCreate = labels.filter((x) => !currentLabels.includes(x))
if (!labelsToCreate.length || conf.dryRun) {
return
}

await Promise.all(
labelsToCreate.map((name) =>
client.issues
.createLabel({
owner: ghOwner,
repo: ghRepo,
...getLabelAttributes(name)
})
.then(() => {
console.log(`Created GitHub label: "${name}"`)
})
)
labelsToCreate.map((name) => {
try {
return client.issues
.createLabel({
owner: ghOwner,
repo: ghRepo,
...getLabelAttributes(name)
})
.then(() => {
console.log(`Created GitHub label: "${name}"`)
})
} catch (err) {
throw new Error(dressError(err, `Failed to create GitHub label '${name}' in repository: ${ghRepo}`))
}
})
)
}

Expand Down
79 changes: 53 additions & 26 deletions lib/snyk.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
'use strict'

const request = require('request-promise-native')
const { dressError } = require('./utils')

const baseV1Url = 'https://snyk.io/api/v1'
const baseRestUrl = 'https://api.snyk.io'
const baseRestUrl = 'https://api.snyk.io/rest'

module.exports = class Snyk {
constructor ({ token, orgId, minimumSeverity }) {
Expand All @@ -29,25 +30,47 @@ module.exports = class Snyk {
).orgs
}

async queryProjectDetails (organizationId, projectId) {
try {
return await request({
method: 'get',
url: `${baseV1Url}/org/${organizationId}/project/${projectId}`,
headers: this._headers,
json: true
})
} catch (err) {
throw new Error(dressError(err, `Failed to query snyk project details. Organization ID: ${organizationId}, Project ID: ${projectId}`))
}
}

async projects (orgId, selectedProjects = []) {
const organizationId = orgId || this._orgId

const responseData = await paginateRestResponseData(
`${baseRestUrl}/rest/orgs/${organizationId}/projects?version=2023-11-27&meta.latest_issue_counts=true&limit=20`,
`${baseRestUrl}/orgs/${organizationId}/projects?version=2023-11-27&meta.latest_issue_counts=true&limit=20`,
this._headers
)

return responseData.map((project) => {
const { critical, high, medium, low } = project.meta.latest_issue_counts
const issueCountTotal = critical + high + medium + low
return {
id: project.id,
name: project.attributes.name,
isMonitored:
project.attributes.status === 'active',
issueCountTotal
}
}).filter(({ id, isMonitored, issueCountTotal }) => {
const projects = await Promise.all(
responseData.map(async (project) => {
const { critical, high, medium, low } = project.meta.latest_issue_counts
const issueCountTotal = critical + high + medium + low

const projectDetails = await this.queryProjectDetails(organizationId, project.id)

return {
id: project.id,
name: project.attributes.name,
isMonitored:
project.attributes.status === 'active',
issueCountTotal,
browseUrl: projectDetails.browseUrl,
imageTag: projectDetails.imageTag
}
})
)

return projects.filter(({ id, isMonitored }) => {
if (selectedProjects.includes(id)) {
return true
}
Expand Down Expand Up @@ -99,18 +122,22 @@ function getSeverities (minimumSeverity) {
}

async function paginateRestResponseData (url, headers, method = 'get') {
const reponseData = []
do {
const response = await request({
method,
url,
headers,
json: true
})
reponseData.push(...response.data)
if (response.links.next) url = baseRestUrl + response.links.next
else url = undefined
} while (url)
try {
const reponseData = []
do {
const response = await request({
method,
url,
headers,
json: true
})
reponseData.push(...response.data)
if (response.links.next) url = baseRestUrl + response.links.next.trimStart('/rest')
else url = undefined
} while (url)

return reponseData
return reponseData
} catch (err) {
throw new Error(dressError(err, `Failed to paginate request for ${method} ${url}`))
}
}
7 changes: 6 additions & 1 deletion lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ const capitalize = (s) => {

const uniq = (array) => [...new Set(array)]

const dressError = (err, msg) => {
return `${msg}, error: ${err.status ? err.status + ' - ' : ''}${err.message}, response: ${err.response}`
}

module.exports = {
capitalize,
compare: {
Expand All @@ -82,5 +86,6 @@ module.exports = {
versionArrays: compareVersionArrays,
arrays: compareArrays
},
uniq
uniq,
dressError
}

0 comments on commit ad3e2b6

Please sign in to comment.