mirror of
https://github.com/dependabot/fetch-metadata.git
synced 2026-03-13 18:17:13 -04:00
@@ -1,15 +1,30 @@
|
||||
import * as YAML from 'yaml'
|
||||
|
||||
export interface updatedDependency {
|
||||
export interface dependencyAlert {
|
||||
alertState: string,
|
||||
ghsaId: string,
|
||||
cvss: number
|
||||
}
|
||||
|
||||
export interface updatedDependency extends dependencyAlert {
|
||||
dependencyName: string,
|
||||
dependencyType: string,
|
||||
updateType: string,
|
||||
directory: string,
|
||||
packageEcosystem: string,
|
||||
targetBranch: string
|
||||
targetBranch: string,
|
||||
prevVersion: string,
|
||||
newVersion: string
|
||||
}
|
||||
|
||||
export function parse (commitMessage: string, branchName: string, mainBranch: string): Array<updatedDependency> {
|
||||
export interface alertLookup {
|
||||
(dependencyName: string, dependencyVersion: string, directory: string): Promise<dependencyAlert>;
|
||||
}
|
||||
|
||||
export async function parse (commitMessage: string, branchName: string, mainBranch: string, lookup: alertLookup): Promise<Array<updatedDependency>> {
|
||||
const firstLine = commitMessage.split('\n')[0]
|
||||
const directory = firstLine.match(/ in (?<directory>\/[^ ]*)$/)
|
||||
const bumpFragment = commitMessage.match(/^Bumps .* from (?<from>\d[^ ]*) to (?<to>\d[^ ]*)\.$/m)
|
||||
const yamlFragment = commitMessage.match(/^-{3}\n(?<dependencies>[\S|\s]*?)\n^\.{3}\n/m)
|
||||
|
||||
if (yamlFragment?.groups && branchName.startsWith('dependabot')) {
|
||||
@@ -18,21 +33,24 @@ export function parse (commitMessage: string, branchName: string, mainBranch: st
|
||||
// Since we are on the `dependabot` branch (9 letters), the 10th letter in the branch name is the delimiter
|
||||
const delim = branchName[10]
|
||||
const chunks = branchName.split(delim)
|
||||
const dirname = chunks.slice(2, -1).join(delim) || '/'
|
||||
const dirname = directory?.groups?.directory ?? "/"
|
||||
const prev = bumpFragment?.groups?.from ?? ""
|
||||
const next = bumpFragment?.groups?.to ?? ""
|
||||
|
||||
if (data['updated-dependencies']) {
|
||||
return data['updated-dependencies'].map(dependency => {
|
||||
return {
|
||||
dependencyName: dependency['dependency-name'],
|
||||
dependencyType: dependency['dependency-type'],
|
||||
updateType: dependency['update-type'],
|
||||
directory: dirname,
|
||||
packageEcosystem: chunks[1],
|
||||
targetBranch: mainBranch
|
||||
}
|
||||
})
|
||||
return await Promise.all(data['updated-dependencies'].map(async (dependency) => ({
|
||||
dependencyName: dependency['dependency-name'],
|
||||
dependencyType: dependency['dependency-type'],
|
||||
updateType: dependency['update-type'],
|
||||
directory: dirname,
|
||||
packageEcosystem: chunks[1],
|
||||
targetBranch: mainBranch,
|
||||
prevVersion: prev,
|
||||
newVersion: next,
|
||||
...await lookup(dependency['dependency-name'], prev, dirname)
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
return []
|
||||
return Promise.resolve([])
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as core from '@actions/core'
|
||||
import { GitHub } from '@actions/github/lib/utils'
|
||||
import { Context } from '@actions/github/lib/context'
|
||||
import type { dependencyAlert } from './update_metadata'
|
||||
|
||||
const DEPENDABOT_LOGIN = 'dependabot[bot]'
|
||||
|
||||
@@ -61,3 +62,41 @@ function warnOtherCommits (): void {
|
||||
'any non-Dependabot changes.'
|
||||
)
|
||||
}
|
||||
|
||||
export async function getAlert (name: string, version: string, directory: string, client: InstanceType<typeof GitHub>, context: Context): Promise<dependencyAlert> {
|
||||
const alerts: any = await client.graphql(`
|
||||
{
|
||||
repository(owner: "${context.repo.owner}", name: "${context.repo.repo}") {
|
||||
vulnerabilityAlerts(first: 100) {
|
||||
nodes {
|
||||
vulnerableManifestFilename
|
||||
vulnerableManifestPath
|
||||
vulnerableRequirements
|
||||
state
|
||||
securityVulnerability {
|
||||
package { name }
|
||||
}
|
||||
securityAdvisory {
|
||||
cvss { score }
|
||||
ghsaId
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`)
|
||||
|
||||
const nodes = alerts?.repository?.vulnerabilityAlerts?.nodes
|
||||
const found = nodes.find(a => a.vulnerableRequirements == `= ${version}`
|
||||
&& trimSlashes(a.vulnerableManifestPath) == `${trimSlashes(directory)}/${a.vulnerableManifestFilename}`
|
||||
&& a.securityVulnerability.package.name == name)
|
||||
|
||||
return {
|
||||
alertState: found?.state ?? "",
|
||||
ghsaId: found?.securityAdvisory.ghsaId ?? "",
|
||||
cvss: found?.securityAdvisory.cvss.score ?? 0.0
|
||||
}
|
||||
}
|
||||
|
||||
export function trimSlashes(value: string): string {
|
||||
return value.replace(/^\//, '').replace(/\/$/, '')
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import * as dotenv from 'dotenv'
|
||||
import { Argv } from 'yargs'
|
||||
import { hideBin } from 'yargs/helpers'
|
||||
|
||||
import { getMessage } from './dependabot/verified_commits'
|
||||
import { getMessage, getAlert } from './dependabot/verified_commits'
|
||||
import { parse } from './dependabot/update_metadata'
|
||||
import { getBranchNames, parseNwo } from './dependabot/util'
|
||||
|
||||
@@ -50,8 +50,9 @@ async function check (args: any): Promise<void> {
|
||||
if (commitMessage) {
|
||||
console.log('This appears to be a valid Dependabot Pull Request.')
|
||||
const branchNames = getBranchNames(newContext)
|
||||
const alertLookup = (name, version, directory) => getAlert(name, version, directory, githubClient, actionContext)
|
||||
|
||||
const updatedDependencies = parse(commitMessage, branchNames.headName, branchNames.baseName)
|
||||
const updatedDependencies = await parse(commitMessage, branchNames.headName, branchNames.baseName, alertLookup)
|
||||
|
||||
if (updatedDependencies.length > 0) {
|
||||
console.log('Updated dependencies:')
|
||||
|
||||
@@ -24,12 +24,13 @@ export async function run (): Promise<void> {
|
||||
// Validate the job
|
||||
const commitMessage = await verifiedCommits.getMessage(githubClient, github.context)
|
||||
const branchNames = util.getBranchNames(github.context)
|
||||
const alertLookup = (name, version, directory) => verifiedCommits.getAlert(name, version, directory, githubClient, github.context)
|
||||
|
||||
if (commitMessage) {
|
||||
// Parse metadata
|
||||
core.info('Parsing Dependabot metadata')
|
||||
|
||||
const updatedDependencies = updateMetadata.parse(commitMessage, branchNames.headName, branchNames.baseName)
|
||||
const updatedDependencies = await updateMetadata.parse(commitMessage, branchNames.headName, branchNames.baseName, alertLookup)
|
||||
|
||||
if (updatedDependencies.length > 0) {
|
||||
output.set(updatedDependencies)
|
||||
|
||||
Reference in New Issue
Block a user