Skip to content

feat!: add support for detect v8 #46

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.createUpgradeReport = exports.createVulnerabilityReport = exports.createLicenseReport = exports.createComponentVulnerabilityReports = exports.createComponentLicenseReports = exports.createComponentReport = exports.createRapidScanReport = void 0;
exports.createComponentReport = exports.createRapidScanReport = void 0;
const core_1 = __nccwpck_require__(2186);
const blackduck_api_1 = __nccwpck_require__(7495);
const inputs_1 = __nccwpck_require__(6180);
Expand Down Expand Up @@ -328,7 +328,7 @@ function createRapidScanReport(policyViolations, blackduckApiService) {
exports.createRapidScanReport = createRapidScanReport;
function createComponentReport(violation, componentVersion, upgradeGuidance, vulnerabilities) {
return {
violatedPolicies: violation.violatingPolicyNames,
violatedPolicies: violation.violatingPolicies.map(x => x.policyName),
name: `${violation.componentName} ${violation.versionName}`,
href: componentVersion === null || componentVersion === void 0 ? void 0 : componentVersion._meta.href,
licenses: createComponentLicenseReports(violation.policyViolationLicenses, componentVersion),
Expand All @@ -341,15 +341,14 @@ exports.createComponentReport = createComponentReport;
function createComponentLicenseReports(policyViolatingLicenses, componentVersion) {
let licenseReport = [];
if (componentVersion === undefined) {
licenseReport = policyViolatingLicenses.map(license => createLicenseReport(license.licenseName, license._meta.href, true));
licenseReport = policyViolatingLicenses.map(license => createLicenseReport(license.name, '', true));
}
else {
const violatingPolicyLicenseNames = policyViolatingLicenses.map(license => license.licenseName);
const violatingPolicyLicenseNames = policyViolatingLicenses.map(license => license.name);
licenseReport = componentVersion.license.licenses.map(license => createLicenseReport(license.name, license.license, violatingPolicyLicenseNames.includes(license.name)));
}
return licenseReport;
}
exports.createComponentLicenseReports = createComponentLicenseReports;
function createComponentVulnerabilityReports(policyViolatingVulnerabilities, componentVulnerabilities) {
let vulnerabilityReport = [];
if (componentVulnerabilities === undefined) {
Expand All @@ -364,15 +363,13 @@ function createComponentVulnerabilityReports(policyViolatingVulnerabilities, com
}
return vulnerabilityReport;
}
exports.createComponentVulnerabilityReports = createComponentVulnerabilityReports;
function createLicenseReport(name, href, violatesPolicy) {
return {
name: name,
href: href,
violatesPolicy: violatesPolicy
};
}
exports.createLicenseReport = createLicenseReport;
function createVulnerabilityReport(name, violatesPolicy, href, cvssScore, severity) {
return {
name: name,
Expand All @@ -382,7 +379,6 @@ function createVulnerabilityReport(name, violatesPolicy, href, cvssScore, severi
severity: severity
};
}
exports.createVulnerabilityReport = createVulnerabilityReport;
function createUpgradeReport(recommendedVersion) {
if (recommendedVersion === undefined) {
return undefined;
Expand All @@ -393,7 +389,6 @@ function createUpgradeReport(recommendedVersion) {
vulnerabilityCount: Object.values(recommendedVersion.vulnerabilityRisk).reduce((accumulatedValues, value) => accumulatedValues + value, 0)
};
}
exports.createUpgradeReport = createUpgradeReport;


/***/ }),
Expand Down Expand Up @@ -437,7 +432,12 @@ exports.createRapidScanReportString = createRapidScanReportString;
function createComponentRow(component) {
const violatedPolicies = component.violatedPolicies.join('<br/>');
const componentInViolation = (component === null || component === void 0 ? void 0 : component.href) ? `[${component.name}](${component.href})` : component.name;
const componentLicenses = component.licenses.map(license => `${license.violatesPolicy ? ':x: &nbsp; ' : ''}[${license.name}](${license.href})`).join('<br/>');
const componentLicenses = component.licenses
.map(license => {
const name = license.href ? `[${license.name}](${license.href})` : license.name;
return `${license.violatesPolicy ? ':x: &nbsp; ' : ''}${name}`;
})
.join('<br/>');
const vulnerabilities = component.vulnerabilities.map(vulnerability => `${vulnerability.violatesPolicy ? ':x: &nbsp; ' : ''}[${vulnerability.name}](${vulnerability.href})${vulnerability.cvssScore && vulnerability.severity ? ` ${vulnerability.severity}: CVSS ${vulnerability.cvssScore}` : ''}`).join('<br/>');
const shortTermString = component.shortTermUpgrade ? `[${component.shortTermUpgrade.name}](${component.shortTermUpgrade.href}) (${component.shortTermUpgrade.vulnerabilityCount} known vulnerabilities)` : '';
const longTermString = component.longTermUpgrade ? `[${component.longTermUpgrade.name}](${component.longTermUpgrade.href}) (${component.longTermUpgrade.vulnerabilityCount} known vulnerabilities)` : '';
Expand Down Expand Up @@ -741,6 +741,7 @@ function runWithPolicyCheck(blackduckPolicyCheck) {
const detectExitCode = yield (0, detect_manager_1.runDetect)(detectPath, detectArgs).catch(reason => {
(0, core_1.setFailed)(`Could not execute ${detect_manager_1.TOOL_NAME} ${inputs_1.DETECT_VERSION}: ${reason}`);
});
(0, core_1.debug)(`Detect exited with code ${detectExitCode}`);
if (detectExitCode === undefined) {
(0, core_1.debug)(`Could not determine ${detect_manager_1.TOOL_NAME} exit code. Canceling policy check.`);
blackduckPolicyCheck.cancelCheck();
Expand Down
2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

139 changes: 88 additions & 51 deletions src/blackduck-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,82 +4,119 @@ import { BearerCredentialHandler } from 'typed-rest-client/Handlers'
import { HttpClient } from 'typed-rest-client/HttpClient'
import { IRestResponse, RestClient } from 'typed-rest-client/RestClient'
import { APPLICATION_NAME } from './application-constants'
export interface IBlackduckView {
_meta: {
href: string
}

export interface BlackDuckView {
_meta: ResourceMetadata
}

export interface IBlackduckItemArray<Type> extends IBlackduckView {
totalCount: number
export interface ResourceMetadata {
href: string
}

export interface BlackDuckPageResponse<Type> {
items: Array<Type>
totalCount: number
}

export interface IUpgradeGuidance {
export interface ComponentVersionUpgradeGuidanceView {
longTerm: ComponentVersionUpgradeGuidanceTermView
shortTerm: ComponentVersionUpgradeGuidanceTermView
version: string
shortTerm: IRecommendedVersion
longTerm: IRecommendedVersion
}

export interface IRecommendedVersion {
/*
Note that this consolidates original API
ComponentVersionUpgradeGuidanceLongTermView and
ComponentVersionUpgradeGuidanceShortTermView since
we only need common attributes
*/
export interface ComponentVersionUpgradeGuidanceTermView {
version: string
versionName: string
vulnerabilityRisk: Object
vulnerabilityRisk: ComponentVersionUpgradeGuidanceVulnerabilityRiskView
}

export interface IComponentSearchResult {
/*
Note that this consolidates original API
ComponentVersionUpgradeGuidanceLongTermVulnerabilityRiskView and
ComponentVersionUpgradeGuidanceShortTermVulnerabilityRiskView since
we only need common attributes
*/
export interface ComponentVersionUpgradeGuidanceVulnerabilityRiskView {
critical: number
high: number
low: number
medium: number
}

export interface ComponentsView {
version: string
versionName: string
}

export interface IComponentVersion {
license: {
licenses: {
license: string
name: string
}[]
}
_meta: {
href: string
}
export interface ComponentVersionView extends BlackDuckView {
license: ComponentVersionLicenseView
}

export interface IComponentVulnerability {
export interface ComponentVersionLicenseView extends BlackDuckView {
licenses: ComponentVersionLicenseLicensesView[]
}

export interface ComponentVersionLicenseLicensesView extends BlackDuckView {
license: string
name: string
}

export interface VulnerabilityView extends BlackDuckView {
cvss2: VulnerabilityCvssView
cvss3: VulnerabilityCvssView
name: string
severity: string
useCvss3: boolean
cvss2: ICvssView
cvss3: ICvssView
_meta: {
href: string
}
}

export interface ICvssView {
/*
Note that this consolidates original API
VulnerabilityCvss2View and
VulnerabilityCvss3View since
we only need common attributes
*/
export interface VulnerabilityCvssView {
baseScore: number
severity: string
}

export interface IRapidScanResults {
export interface DeveloperScansScanView extends BlackDuckView {
componentIdentifier: string
componentName: string
policyViolationLicenses: DeveloperScansScanItemsPolicyViolationView[]
policyViolationVulnerabilities: DeveloperScansScanItemsPolicyViolationView[]
versionName: string
componentIdentifier: string
violatingPolicyNames: string[]
policyViolationVulnerabilities: IRapidScanVulnerability[]
policyViolationLicenses: IRapidScanLicense[]
_meta: {
href: string
}
violatingPolicies: DeveloperScansScanItemsViolatingPoliciesView[]
}

export interface IRapidScanVulnerability {
name: string
/*
Note that this consolidates original API
DeveloperScansScanItemsPolicyViolationLicensesViolatingPoliciesView,
DeveloperScansScanItemsPolicyViolationVulnerabilitiesViolatingPoliciesView and
DeveloperScansScanItemsViolatingPoliciesView since
we only need common attributes
*/
export interface DeveloperScansScanItemsViolatingPoliciesView {
description: string
policyName: string
policySeverity: string
policyStatus: string
}

export interface IRapidScanLicense {
licenseName: string
_meta: {
href: string
}
/*
Note that this consolidates original API
DeveloperScansScanItemsPolicyViolationLicensesView and
DeveloperScansScanItemsPolicyViolationVulnerabilitiesView since
we only need common attributes
*/
export interface DeveloperScansScanItemsPolicyViolationView {
name: string
}

export class BlackduckApiService {
Expand Down Expand Up @@ -123,34 +160,34 @@ export class BlackduckApiService {
})
}

async getUpgradeGuidanceFor(bearerToken: string, componentVersion: IComponentVersion): Promise<IRestResponse<IUpgradeGuidance>> {
async getUpgradeGuidanceFor(bearerToken: string, componentVersion: ComponentVersionView): Promise<IRestResponse<ComponentVersionUpgradeGuidanceView>> {
return this.get(bearerToken, `${componentVersion._meta.href}/upgrade-guidance`)
}

async getComponentsMatching(bearerToken: string, componentIdentifier: string, limit: number = 10): Promise<IRestResponse<IBlackduckItemArray<IComponentSearchResult>>> {
async getComponentsMatching(bearerToken: string, componentIdentifier: string, limit: number = 10): Promise<IRestResponse<BlackDuckPageResponse<ComponentsView>>> {
const requestPath = `/api/components?q=${componentIdentifier}`

return this.requestPage(bearerToken, requestPath, 0, limit)
}

async getComponentVersion(bearerToken: string, searchResult: IComponentSearchResult) {
async getComponentVersion(bearerToken: string, searchResult: ComponentsView) {
return this.get(bearerToken, searchResult.version)
}

async getComponentVersionMatching(bearerToken: string, componentIdentifier: string, limit: number = 10): Promise<IComponentVersion | null> {
async getComponentVersionMatching(bearerToken: string, componentIdentifier: string, limit: number = 10): Promise<ComponentVersionView | null> {
const componentSearchResponse = await this.getComponentsMatching(bearerToken, componentIdentifier, limit)
const firstMatchingComponentVersionUrl = componentSearchResponse?.result?.items[0].version

let componentVersion = null
if (firstMatchingComponentVersionUrl !== undefined) {
const componentVersionResponse: IRestResponse<IComponentVersion> = await this.get(bearerToken, firstMatchingComponentVersionUrl)
const componentVersionResponse: IRestResponse<ComponentVersionView> = await this.get(bearerToken, firstMatchingComponentVersionUrl)
componentVersion = componentVersionResponse?.result
}

return componentVersion
}

async getComponentVulnerabilties(bearerToken: string, componentVersion: IComponentVersion): Promise<IRestResponse<IBlackduckItemArray<IComponentVulnerability>>> {
async getComponentVulnerabilties(bearerToken: string, componentVersion: ComponentVersionView): Promise<IRestResponse<BlackDuckPageResponse<VulnerabilityView>>> {
return this.get(bearerToken, `${componentVersion._meta.href}/vulnerabilities`, 'application/vnd.blackducksoftware.vulnerability-4+json')
}

Expand All @@ -161,7 +198,7 @@ export class BlackduckApiService {
return this.requestPage(bearerToken, requestPath, 0, limit)
}

async requestPage(bearerToken: string, requestPath: string, offset: number, limit: number): Promise<IRestResponse<IBlackduckItemArray<any>>> {
async requestPage(bearerToken: string, requestPath: string, offset: number, limit: number): Promise<IRestResponse<BlackDuckPageResponse<any>>> {
return this.get(bearerToken, `${this.blackduckUrl}${requestPath}&offset=${offset}&limit=${limit}`)
}

Expand Down
22 changes: 11 additions & 11 deletions src/detect/report.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { warning } from '@actions/core'
import { BlackduckApiService, IComponentVersion, IComponentVulnerability, IRapidScanLicense, IRapidScanResults, IRapidScanVulnerability, IRecommendedVersion, IUpgradeGuidance } from '../blackduck-api'
import { BlackduckApiService, ComponentVersionView, VulnerabilityView, DeveloperScansScanView, ComponentVersionUpgradeGuidanceView, DeveloperScansScanItemsPolicyViolationView, ComponentVersionUpgradeGuidanceTermView } from '../blackduck-api'
import { BLACKDUCK_API_TOKEN, BLACKDUCK_URL } from '../inputs'

export async function createRapidScanReport(policyViolations: IRapidScanResults[], blackduckApiService?: BlackduckApiService): Promise<IComponentReport[]> {
export async function createRapidScanReport(policyViolations: DeveloperScansScanView[], blackduckApiService?: BlackduckApiService): Promise<IComponentReport[]> {
const rapidScanReport: IComponentReport[] = []

if (blackduckApiService === undefined) {
Expand Down Expand Up @@ -54,9 +54,9 @@ export interface IComponentReport {
longTermUpgrade?: IUpgradeReport
}

export function createComponentReport(violation: IRapidScanResults, componentVersion?: IComponentVersion, upgradeGuidance?: IUpgradeGuidance, vulnerabilities?: IComponentVulnerability[]): IComponentReport {
export function createComponentReport(violation: DeveloperScansScanView, componentVersion?: ComponentVersionView, upgradeGuidance?: ComponentVersionUpgradeGuidanceView, vulnerabilities?: VulnerabilityView[]): IComponentReport {
return {
violatedPolicies: violation.violatingPolicyNames,
violatedPolicies: violation.violatingPolicies.map(x => x.policyName),
name: `${violation.componentName} ${violation.versionName}`,
href: componentVersion?._meta.href,
licenses: createComponentLicenseReports(violation.policyViolationLicenses, componentVersion),
Expand All @@ -66,19 +66,19 @@ export function createComponentReport(violation: IRapidScanResults, componentVer
}
}

export function createComponentLicenseReports(policyViolatingLicenses: IRapidScanLicense[], componentVersion?: IComponentVersion): ILicenseReport[] {
function createComponentLicenseReports(policyViolatingLicenses: DeveloperScansScanItemsPolicyViolationView[], componentVersion?: ComponentVersionView): ILicenseReport[] {
let licenseReport = []
if (componentVersion === undefined) {
licenseReport = policyViolatingLicenses.map(license => createLicenseReport(license.licenseName, license._meta.href, true))
licenseReport = policyViolatingLicenses.map(license => createLicenseReport(license.name, '', true))
} else {
const violatingPolicyLicenseNames = policyViolatingLicenses.map(license => license.licenseName)
const violatingPolicyLicenseNames = policyViolatingLicenses.map(license => license.name)
licenseReport = componentVersion.license.licenses.map(license => createLicenseReport(license.name, license.license, violatingPolicyLicenseNames.includes(license.name)))
}

return licenseReport
}

export function createComponentVulnerabilityReports(policyViolatingVulnerabilities: IRapidScanVulnerability[], componentVulnerabilities?: IComponentVulnerability[]): IVulnerabilityReport[] {
function createComponentVulnerabilityReports(policyViolatingVulnerabilities: DeveloperScansScanItemsPolicyViolationView[], componentVulnerabilities?: VulnerabilityView[]): IVulnerabilityReport[] {
let vulnerabilityReport = []
if (componentVulnerabilities === undefined) {
vulnerabilityReport = policyViolatingVulnerabilities.map(vulnerability => createVulnerabilityReport(vulnerability.name, true))
Expand All @@ -99,7 +99,7 @@ export interface ILicenseReport {
violatesPolicy: boolean
}

export function createLicenseReport(name: string, href: string, violatesPolicy: boolean): ILicenseReport {
function createLicenseReport(name: string, href: string, violatesPolicy: boolean): ILicenseReport {
return {
name: name,
href: href,
Expand All @@ -115,7 +115,7 @@ export interface IVulnerabilityReport {
severity?: string
}

export function createVulnerabilityReport(name: string, violatesPolicy: boolean, href?: string, cvssScore?: number, severity?: string): IVulnerabilityReport {
function createVulnerabilityReport(name: string, violatesPolicy: boolean, href?: string, cvssScore?: number, severity?: string): IVulnerabilityReport {
return {
name: name,
violatesPolicy: violatesPolicy,
Expand All @@ -131,7 +131,7 @@ export interface IUpgradeReport {
vulnerabilityCount: number
}

export function createUpgradeReport(recommendedVersion?: IRecommendedVersion): IUpgradeReport | undefined {
function createUpgradeReport(recommendedVersion?: ComponentVersionUpgradeGuidanceTermView): IUpgradeReport | undefined {
if (recommendedVersion === undefined) {
return undefined
}
Expand Down
Loading