Skip to content

Commit

Permalink
SCP-85 Input sbom.json by default
Browse files Browse the repository at this point in the history
  • Loading branch information
isasmendiagus authored Jan 31, 2024
1 parent 6d649dd commit 2e98329
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 41 deletions.
1 change: 0 additions & 1 deletion .github/workflows/test-action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ jobs:
id: test-action
uses: ./
with:
sbom.enabled: false
dependencies.enabled: true
policies: copyleft, undeclared

Expand Down
78 changes: 58 additions & 20 deletions dist/index.js

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

Empty file removed results.json
Empty file.
13 changes: 5 additions & 8 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { getLicenses, readResult } from './services/result.service';
import { createCommentOnPR, isPullRequest } from './utils/github.utils';
import { CopyleftPolicyCheck } from './policies/copyleft-policy-check';
import { generateJobSummary, generateSummary } from './services/report.service';
import * as core from '@actions/core';
import * as exec from '@actions/exec';
import * as inputs from './app.input';
import * as outputs from './app.output';

import { commandBuilder, uploadResults } from './services/scan.service';
import { scanService, uploadResults } from './services/scan.service';
/**
* The main function for the action.
* @returns {Promise<void>} Resolves when the action is complete.
Expand All @@ -22,20 +20,19 @@ export async function run(): Promise<void> {
policies.forEach(async policy => policy.start());

// run scan
const { stdout, stderr } = await exec.getExecOutput(commandBuilder(), []);
const { scan, stdout } = await scanService.scan();
await uploadResults();
const scannerResults = await readResult(inputs.OUTPUT_FILEPATH);

// run policies
policies.forEach(async policy => await policy.run(scannerResults));
policies.forEach(async policy => await policy.run(scan));

if (isPullRequest()) {
// create reports
const report = generateSummary(scannerResults);
const report = generateSummary(scan);
createCommentOnPR(report);
}

await generateJobSummary(scannerResults);
await generateJobSummary(scan);
// set outputs for other workflow steps to use
core.setOutput(outputs.RESULT_FILEPATH, inputs.OUTPUT_FILEPATH);
core.setOutput(outputs.STDOUT_SCAN_COMMAND, stdout);
Expand Down
83 changes: 71 additions & 12 deletions src/services/scan.service.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,81 @@
import path from 'path';
import * as input from '../app.input';
import { DefaultArtifactClient } from '@actions/artifact';
import * as exec from '@actions/exec';
import * as inputs from '../app.input';
import { ScannerResults } from './result.interfaces';
import fs from 'fs';
import * as core from '@actions/core';
import * as path from 'path';

const artifact = new DefaultArtifactClient();

export async function uploadResults(): Promise<void> {
await artifact.uploadArtifact(
path.basename(input.OUTPUT_FILEPATH),
[input.OUTPUT_FILEPATH],
path.dirname(input.OUTPUT_FILEPATH)
path.basename(inputs.OUTPUT_FILEPATH),
[inputs.OUTPUT_FILEPATH],
path.dirname(inputs.OUTPUT_FILEPATH)
);
}

export function commandBuilder(): string {
return `docker run -v "${input.REPO_DIR}":"/scanoss" ghcr.io/scanoss/scanoss-py:v1.9.0 scan .
--output ${input.OUTPUT_FILEPATH}
${input.DEPENDENCIES_ENABLED ? `--dependencies` : ''}
${input.SBOM_ENABLED ? `--${input.SBOM_TYPE} ${input.SBOM_FILEPATH}` : ''}
${input.API_URL ? `--apiurl ${input.API_URL}` : ''}
${input.API_KEY ? `--key ${input.API_KEY}` : ''}`.replace(/\n/gm, '');
export interface Options {
sbomType?: string;
sbomEnabled?: boolean;
sbomFilepath?: string;

dependenciesEnabled?: boolean;

apiKey?: string;
apiUrl?: string;

outputFilepath: string;
inputFilepath: string;
}

export class ScanService {
private options: Options;
constructor(options?: Options) {
this.options = options || {
sbomFilepath: inputs.SBOM_FILEPATH,
sbomType: inputs.SBOM_TYPE,
sbomEnabled: inputs.SBOM_ENABLED,
apiKey: inputs.API_KEY,
apiUrl: inputs.API_URL,
dependenciesEnabled: inputs.DEPENDENCIES_ENABLED,
outputFilepath: inputs.OUTPUT_FILEPATH,
inputFilepath: inputs.REPO_DIR
};
}
async scan(): Promise<{ scan: ScannerResults; stdout: string; stderr: string }> {
const command = await this.buildCommand();
const { stdout, stderr } = await exec.getExecOutput(command, []);
const scan = await this.parseResult();
return { scan, stdout, stderr };
}

private async buildCommand(): Promise<string> {
return `docker run -v "${this.options.inputFilepath}":"/scanoss" ghcr.io/scanoss/scanoss-py:v1.9.0 scan .
--output ${this.options.outputFilepath}
${this.options.dependenciesEnabled ? `--dependencies` : ''}
${await this.detectSbom()}
${this.options.apiUrl ? `--apiurl ${this.options.apiUrl}` : ''}
${this.options.apiKey ? `--key ${this.options.apiKey}` : ''}`.replace(/\n/gm, ' ');
}

private async detectSbom(): Promise<string> {
if (!this.options.sbomEnabled || !this.options.sbomFilepath) return '';

try {
await fs.promises.access(this.options.sbomFilepath, fs.constants.F_OK);
return `--${this.options.sbomType} ${this.options.sbomFilepath}`;
} catch (error) {
core.warning('SBOM not found');
return '';
}
}

private async parseResult(): Promise<ScannerResults> {
const content = await fs.promises.readFile(this.options.outputFilepath, 'utf-8');
return JSON.parse(content) as ScannerResults;
}
}

export const scanService = new ScanService();

0 comments on commit 2e98329

Please sign in to comment.