Skip to content

Commit

Permalink
Merge pull request #146 from pangaeatech/get_compat_score
Browse files Browse the repository at this point in the history
Return compatibility score
  • Loading branch information
brrygrdn committed Feb 28, 2022
2 parents f4b2d0d + e050770 commit 0ca01a5
Show file tree
Hide file tree
Showing 12 changed files with 160 additions and 22 deletions.
8 changes: 7 additions & 1 deletion README.md
Expand Up @@ -25,6 +25,7 @@ jobs:
uses: dependabot/fetch-metadata@v1.2.1
with:
alert-lookup: true
compat-lookup: true
```

Supported inputs are:
Expand All @@ -33,7 +34,10 @@ Supported inputs are:
- The `GITHUB_TOKEN` secret
- Defaults to `${{ github.token }}`
- `alert-lookup` (boolean)
- If `true`, then call populate the `alert-state`, `ghsa-id` and `cvss` outputs.
- If `true`, then populate the `alert-state`, `ghsa-id` and `cvss` outputs.
- Defaults to `false`
- `compat-lookup` (boolean)
- If `true`, then populate the `compatibility-score` output.
- Defaults to `false`

Subsequent actions will have access to the following outputs:
Expand Down Expand Up @@ -62,6 +66,8 @@ Subsequent actions will have access to the following outputs:
- If this PR is associated with a security alert and `alert-lookup` is `true`, this contains the GHSA-ID of that alert.
- `steps.dependabot-metadata.outputs.cvss`
- If this PR is associated with a security alert and `alert-lookup` is `true`, this contains the CVSS value of that alert (otherwise it contains 0).
- `steps.dependabot-metadata.outputs.compatibility-score`
- If this PR has a known compatibility score and `compat-lookup` is `true`, this contains the compatibility score (otherwise it contains 0).

**Note:** These outputs will only be populated if the target Pull Request was opened by Dependabot and contains
**only** Dependabot-created commits.
Expand Down
7 changes: 6 additions & 1 deletion action.yml
Expand Up @@ -6,7 +6,10 @@ branding:
inputs:
alert-lookup:
type: boolean
description: 'If true, then call populate the `alert-state`, `ghsa-id` and `cvss` outputs'
description: 'If true, then populate the `alert-state`, `ghsa-id` and `cvss` outputs'
compat-lookup:
type: boolean
description: 'If true, then populate the `compatibility-score` output'
github-token:
description: 'The GITHUB_TOKEN secret'
default: ${{ github.token }}
Expand Down Expand Up @@ -35,6 +38,8 @@ outputs:
description: 'If this PR is associated with a security alert and `alert-lookup` is `true`, this contains the GHSA-ID of that alert.'
cvss:
description: 'If this PR is associated with a security alert and `alert-lookup` is `true`, this contains the CVSS value of that alert (otherwise it contains 0).'
compatibility-score:
description: 'If this PR has a known compatibility score and `compat-lookup` is `true`, this contains the compatibility score (otherwise it contains 0).'
runs:
using: 'node12'
main: 'dist/index.js'
33 changes: 29 additions & 4 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/dependabot/output.test.ts
Expand Up @@ -18,6 +18,7 @@ const baseDependency = {
targetBranch: '',
prevVersion: '',
newVersion: '',
compatScore: 0,
alertState: '',
ghsaId: '',
cvss: 0
Expand All @@ -34,6 +35,7 @@ test('when given a single dependency it sets its values', async () => {
targetBranch: 'main',
prevVersion: '1.0.2',
newVersion: '1.1.3-beta',
compatScore: 43,
alertState: 'FIXED',
ghsaId: 'VERY_LONG_ID',
cvss: 4.6
Expand All @@ -56,6 +58,7 @@ test('when given a single dependency it sets its values', async () => {
expect(core.setOutput).toBeCalledWith('target-branch', 'main')
expect(core.setOutput).toBeCalledWith('previous-version', '1.0.2')
expect(core.setOutput).toBeCalledWith('new-version', '1.1.3-beta')
expect(core.setOutput).toBeCalledWith('compatibility-score', 43)
expect(core.setOutput).toBeCalledWith('alert-state', 'FIXED')
expect(core.setOutput).toBeCalledWith('ghsa-id', 'VERY_LONG_ID')
expect(core.setOutput).toBeCalledWith('cvss', 4.6)
Expand Down Expand Up @@ -101,6 +104,7 @@ test('when given a multiple dependencies, it uses the highest values for types',
expect(core.setOutput).toBeCalledWith('target-branch', '')
expect(core.setOutput).toBeCalledWith('previous-version', '')
expect(core.setOutput).toBeCalledWith('new-version', '')
expect(core.setOutput).toBeCalledWith('compatibility-score', 0)
expect(core.setOutput).toBeCalledWith('alert-state', '')
expect(core.setOutput).toBeCalledWith('ghsa-id', '')
expect(core.setOutput).toBeCalledWith('cvss', 0)
Expand Down Expand Up @@ -131,6 +135,7 @@ test('when the dependency has no update type', async () => {
expect(core.setOutput).toBeCalledWith('target-branch', '')
expect(core.setOutput).toBeCalledWith('previous-version', '')
expect(core.setOutput).toBeCalledWith('new-version', '')
expect(core.setOutput).toBeCalledWith('compatibility-score', 0)
expect(core.setOutput).toBeCalledWith('alert-state', '')
expect(core.setOutput).toBeCalledWith('ghsa-id', '')
expect(core.setOutput).toBeCalledWith('cvss', 0)
Expand Down Expand Up @@ -174,6 +179,7 @@ test('when given a multiple dependencies, and some do not have update types', as
expect(core.setOutput).toBeCalledWith('target-branch', '')
expect(core.setOutput).toBeCalledWith('previous-version', '')
expect(core.setOutput).toBeCalledWith('new-version', '')
expect(core.setOutput).toBeCalledWith('compatibility-score', 0)
expect(core.setOutput).toBeCalledWith('alert-state', '')
expect(core.setOutput).toBeCalledWith('ghsa-id', '')
expect(core.setOutput).toBeCalledWith('cvss', 0)
Expand Down
3 changes: 3 additions & 0 deletions src/dependabot/output.ts
Expand Up @@ -26,6 +26,7 @@ export function set (updatedDependencies: Array<updatedDependency>): void {
const target = firstDependency?.targetBranch
const prevVersion = firstDependency?.prevVersion
const newVersion = firstDependency?.newVersion
const compatScore = firstDependency?.compatScore
const alertState = firstDependency?.alertState
const ghsaId = firstDependency?.ghsaId
const cvss = firstDependency?.cvss
Expand All @@ -39,6 +40,7 @@ export function set (updatedDependencies: Array<updatedDependency>): void {
core.info(`outputs.target-branch: ${target}`)
core.info(`outputs.previous-version: ${prevVersion}`)
core.info(`outputs.new-version: ${newVersion}`)
core.info(`outputs.compatibility-score: ${compatScore}`)
core.info(`outputs.alert-state: ${alertState}`)
core.info(`outputs.ghsa-id: ${ghsaId}`)
core.info(`outputs.cvss: ${cvss}`)
Expand All @@ -53,6 +55,7 @@ export function set (updatedDependencies: Array<updatedDependency>): void {
core.setOutput('target-branch', target)
core.setOutput('previous-version', prevVersion)
core.setOutput('new-version', newVersion)
core.setOutput('compatibility-score', compatScore)
core.setOutput('alert-state', alertState)
core.setOutput('ghsa-id', ghsaId)
core.setOutput('cvss', cvss)
Expand Down
30 changes: 23 additions & 7 deletions src/dependabot/update_metadata.test.ts
Expand Up @@ -2,7 +2,8 @@ import * as updateMetadata from './update_metadata'

test('it returns an empty array for a blank string', async () => {
const getAlert = async () => Promise.resolve({ alertState: 'DISMISSED', ghsaId: 'GHSA-III-BBB', cvss: 4.6 })
expect(updateMetadata.parse('', 'dependabot/nuget/coffee-rails', 'main', getAlert)).resolves.toEqual([])
const getScore = async () => Promise.resolve(43)
expect(updateMetadata.parse('', 'dependabot/nuget/coffee-rails', 'main', getAlert, getScore)).resolves.toEqual([])
})

test('it returns an empty array for commit message with no dependabot yaml fragment', async () => {
Expand All @@ -14,7 +15,8 @@ test('it returns an empty array for commit message with no dependabot yaml fragm
Signed-off-by: dependabot[bot] <support@github.com>`

const getAlert = async () => Promise.resolve({ alertState: 'DISMISSED', ghsaId: 'GHSA-III-BBB', cvss: 4.6 })
expect(updateMetadata.parse(commitMessage, 'dependabot/nuget/coffee-rails', 'main', getAlert)).resolves.toEqual([])
const getScore = async () => Promise.resolve(43)
expect(updateMetadata.parse(commitMessage, 'dependabot/nuget/coffee-rails', 'main', getAlert, getScore)).resolves.toEqual([])
})

test('it returns the updated dependency information when there is a yaml fragment', async () => {
Expand All @@ -34,7 +36,8 @@ test('it returns the updated dependency information when there is a yaml fragmen
'Signed-off-by: dependabot[bot] <support@github.com>'

const getAlert = async () => Promise.resolve({ alertState: 'DISMISSED', ghsaId: 'GHSA-III-BBB', cvss: 4.6 })
const updatedDependencies = await updateMetadata.parse(commitMessage, 'dependabot/nuget/coffee-rails', 'main', getAlert)
const getScore = async () => Promise.resolve(43)
const updatedDependencies = await updateMetadata.parse(commitMessage, 'dependabot/nuget/coffee-rails', 'main', getAlert, getScore)

expect(updatedDependencies).toHaveLength(1)

Expand All @@ -46,6 +49,7 @@ test('it returns the updated dependency information when there is a yaml fragmen
expect(updatedDependencies[0].targetBranch).toEqual('main')
expect(updatedDependencies[0].prevVersion).toEqual('4.0.1')
expect(updatedDependencies[0].newVersion).toEqual('4.2.2')
expect(updatedDependencies[0].compatScore).toEqual(43)
expect(updatedDependencies[0].alertState).toEqual('DISMISSED')
expect(updatedDependencies[0].ghsaId).toEqual('GHSA-III-BBB')
expect(updatedDependencies[0].cvss).toEqual(4.6)
Expand Down Expand Up @@ -78,7 +82,15 @@ test('it supports multiple dependencies within a single fragment', async () => {
return Promise.resolve({ alertState: '', ghsaId: '', cvss: 0 })
}

const updatedDependencies = await updateMetadata.parse(commitMessage, 'dependabot/nuget/api/main/coffee-rails', 'main', getAlert)
const getScore = async (name: string) => {
if (name === 'coffee-rails') {
return Promise.resolve(34)
}

return Promise.resolve(0)
}

const updatedDependencies = await updateMetadata.parse(commitMessage, 'dependabot/nuget/api/main/coffee-rails', 'main', getAlert, getScore)

expect(updatedDependencies).toHaveLength(2)

Expand All @@ -90,6 +102,7 @@ test('it supports multiple dependencies within a single fragment', async () => {
expect(updatedDependencies[0].targetBranch).toEqual('main')
expect(updatedDependencies[0].prevVersion).toEqual('4.0.1')
expect(updatedDependencies[0].newVersion).toEqual('4.2.2')
expect(updatedDependencies[0].compatScore).toEqual(34)
expect(updatedDependencies[0].alertState).toEqual('DISMISSED')
expect(updatedDependencies[0].ghsaId).toEqual('GHSA-III-BBB')
expect(updatedDependencies[0].cvss).toEqual(4.6)
Expand All @@ -101,7 +114,7 @@ test('it supports multiple dependencies within a single fragment', async () => {
expect(updatedDependencies[1].packageEcosystem).toEqual('nuget')
expect(updatedDependencies[1].targetBranch).toEqual('main')
expect(updatedDependencies[1].prevVersion).toEqual('')
expect(updatedDependencies[1].newVersion).toEqual('')
expect(updatedDependencies[1].compatScore).toEqual(0)
expect(updatedDependencies[1].alertState).toEqual('')
expect(updatedDependencies[1].ghsaId).toEqual('')
expect(updatedDependencies[1].cvss).toEqual(0)
Expand Down Expand Up @@ -129,7 +142,7 @@ test('it only returns information within the first fragment if there are multipl
'\n' +
'Signed-off-by: dependabot[bot] <support@github.com>'

const updatedDependencies = await updateMetadata.parse(commitMessage, 'dependabot|nuget|coffee-rails', 'main', undefined)
const updatedDependencies = await updateMetadata.parse(commitMessage, 'dependabot|nuget|coffee-rails', 'main', undefined, undefined)

expect(updatedDependencies).toHaveLength(1)

Expand All @@ -141,6 +154,7 @@ test('it only returns information within the first fragment if there are multipl
expect(updatedDependencies[0].targetBranch).toEqual('main')
expect(updatedDependencies[0].prevVersion).toEqual('')
expect(updatedDependencies[0].newVersion).toEqual('')
expect(updatedDependencies[0].compatScore).toEqual(0)
expect(updatedDependencies[0].alertState).toEqual('')
expect(updatedDependencies[0].ghsaId).toEqual('')
expect(updatedDependencies[0].cvss).toEqual(0)
Expand All @@ -162,7 +176,8 @@ test('it properly handles dependencies which contain slashes', async () => {
'Signed-off-by: dependabot[bot] <support@github.com>'

const getAlert = async () => Promise.resolve({ alertState: '', ghsaId: '', cvss: 0 })
const updatedDependencies = await updateMetadata.parse(commitMessage, 'dependabot/nuget/api/rails/coffee', 'main', getAlert)
const getScore = async () => Promise.resolve(0)
const updatedDependencies = await updateMetadata.parse(commitMessage, 'dependabot/nuget/api/rails/coffee', 'main', getAlert, getScore)

expect(updatedDependencies).toHaveLength(1)

Expand All @@ -174,6 +189,7 @@ test('it properly handles dependencies which contain slashes', async () => {
expect(updatedDependencies[0].targetBranch).toEqual('main')
expect(updatedDependencies[0].prevVersion).toEqual('')
expect(updatedDependencies[0].newVersion).toEqual('')
expect(updatedDependencies[0].compatScore).toEqual(0)
expect(updatedDependencies[0].alertState).toEqual('')
expect(updatedDependencies[0].ghsaId).toEqual('')
expect(updatedDependencies[0].cvss).toEqual(0)
Expand Down

0 comments on commit 0ca01a5

Please sign in to comment.