Skip to content

Commit

Permalink
SCP-48 Extract licenses from results
Browse files Browse the repository at this point in the history
  • Loading branch information
isasmendiagus authored and francostramana committed Jan 22, 2024
1 parent 73dbc23 commit dc762bf
Show file tree
Hide file tree
Showing 9 changed files with 297 additions and 42 deletions.
24 changes: 9 additions & 15 deletions .github/workflows/test-action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,30 @@ on:
pull_request:
push:
branches:
- main
- '*'

permissions:
contents: read

jobs:
test-action:
name: GitHub Actions Test
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
runs-on: ubuntu-latest

steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4

- name: Setup Python
id: setup-python
uses: actions/setup-python@v5
with:
python-version: '3.10'

- run: pip install scanoss[fast_winnowing] scancode-toolkit

- name: Test Local Action
id: test-action
uses: ./

- name: Print Output
id: output
- name: Print output command
run: echo "${{ steps.test-action.outputs.output-command }}"

- name: Print Licenses
run: echo "${{ steps.test-action.outputs.licenses }}"

- name: Print Result
run: cat "${{ steps.test-action.outputs.result-filepath }}"
2 changes: 1 addition & 1 deletion .prettierrc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{

Check warning on line 1 in .prettierrc.json

View workflow job for this annotation

GitHub Actions / Lint Codebase

File ignored by default.
"printWidth": 80,
"printWidth": 120,
"tabWidth": 2,
"useTabs": false,
"semi": false,
Expand Down
21 changes: 4 additions & 17 deletions __tests__/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,9 @@ describe('action', () => {

// Verify that all of the core library functions were called correctly
expect(debugMock).toHaveBeenNthCalledWith(1, 'Waiting 500 milliseconds ...')
expect(debugMock).toHaveBeenNthCalledWith(
2,
expect.stringMatching(timeRegex)
)
expect(debugMock).toHaveBeenNthCalledWith(
3,
expect.stringMatching(timeRegex)
)
expect(setOutputMock).toHaveBeenNthCalledWith(
1,
'time',
expect.stringMatching(timeRegex)
)
expect(debugMock).toHaveBeenNthCalledWith(2, expect.stringMatching(timeRegex))
expect(debugMock).toHaveBeenNthCalledWith(3, expect.stringMatching(timeRegex))
expect(setOutputMock).toHaveBeenNthCalledWith(1, 'time', expect.stringMatching(timeRegex))
expect(errorMock).not.toHaveBeenCalled()
})

Expand All @@ -80,10 +70,7 @@ describe('action', () => {
expect(runMock).toHaveReturned()

// Verify that all of the core library functions were called correctly
expect(setFailedMock).toHaveBeenNthCalledWith(
1,
'milliseconds not a number'
)
expect(setFailedMock).toHaveBeenNthCalledWith(1, 'milliseconds not a number')
expect(errorMock).not.toHaveBeenCalled()
})
})
93 changes: 90 additions & 3 deletions dist/index.js

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

Empty file added results.json
Empty file.
20 changes: 14 additions & 6 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,42 @@
import * as core from '@actions/core'
import * as exec from '@actions/exec'
import { getLicenses, readResult } from './services/result.service'

/**
* The main function for the action.
* @returns {Promise<void>} Resolves when the action is complete.
*/
export async function run(): Promise<void> {
try {
const scanParams: string = core.getInput('scan-parameters')

const repoDir = process.env.GITHUB_WORKSPACE as string
const outputPath = 'results.json'

// Declara las opciones para ejecutar el exec
const options: exec.ExecOptions = {}
let output: string = ''
let output = ''
options.listeners = {
stdout: (data: Buffer) => {
output += data.toString()
},
stderr: (data: Buffer) => {
output += data.toString()
}
}
options.silent = true

// run scan
await exec.exec(
'scanoss-py',
['scan', repoDir, '--output', outputPath],
`docker run -v "${repoDir}":"/scanoss" ghcr.io/scanoss/scanoss-py:v1.9.0 scan . --output ${outputPath}`,
[],
options
)

const scannerResults = await readResult(outputPath)
const licenses = getLicenses(scannerResults)

core.setOutput('licenses', licenses.toString())

core.setOutput('output-command', output)

// set outputs for other workflow steps to use
core.setOutput('result-filepath', outputPath)
} catch (error) {
Expand Down
95 changes: 95 additions & 0 deletions src/services/result.interfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
export type ScannerResults = Record<string, ScannerComponent[] | DependencyComponent[]>

export enum ComponentID {

Check failure on line 3 in src/services/result.interfaces.ts

View workflow job for this annotation

GitHub Actions / TypeScript Tests

'ComponentID' is already declared in the upper scope on line 3 column 13

Check failure on line 3 in src/services/result.interfaces.ts

View workflow job for this annotation

GitHub Actions / Lint Codebase

'ComponentID' is already declared in the upper scope on line 3 column 13
NONE = 'none',
FILE = 'file',
SNIPPET = 'snippet',
DEPENDENCY = 'dependency'
}

interface CommonComponent {
id: ComponentID
status: string
}

export interface DependencyComponent extends CommonComponent {
dependencies: {
licenses: {
is_spdx_approved: boolean
name: string
spdx_id: string
}[]
purl: string
url: string
version: string
}[]
}

export interface ScannerComponent extends CommonComponent {
lines: string
oss_lines: string
matched: string
purl: string[]
vendor: string
component: string
version: string
latest: string
url: string
release_date: string
file: string
url_hash: string
file_hash: string
source_hash: string
file_url: string
licenses: {
name: string
patent_hints: string
copyleft: string
checklist_url: string
osadl_updated: string
source: string
incompatible_with?: string
}[]
dependencies: {
vendor: string
component: string
version: string
source: string
}[]
copyrights: {
name: string
source: string
}[]
vulnerabilities: {
ID: string
CVE: string
severity: string
reported: string
introduced: string
patched: string
summary: string
source: string
}[]
quality: {
score: string
source: string
}[]
cryptography: any[]

Check failure on line 77 in src/services/result.interfaces.ts

View workflow job for this annotation

GitHub Actions / TypeScript Tests

Unexpected any. Specify a different type

Check failure on line 77 in src/services/result.interfaces.ts

View workflow job for this annotation

GitHub Actions / Lint Codebase

Unexpected any. Specify a different type
health: {
creation_date: string
issues: number
last_push: string
last_update: string
watchers: number
country: string
stars: number
forks: number
}
server: {
version: string
kb_version: { monthly: string; daily: string }
hostname: string
flags: string
elapsed: string
}
}
32 changes: 32 additions & 0 deletions src/services/result.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { ComponentID, DependencyComponent, ScannerComponent, ScannerResults } from './result.interfaces'
import * as fs from 'fs'

export async function readResult(filepath: string): Promise<ScannerResults> {
const content = await fs.promises.readFile(filepath, 'utf-8')
return JSON.parse(content) as ScannerResults
}

export function getLicenses(results: ScannerResults): string[] {
const licenses = new Set<string>()

for (const component of Object.values(results)) {
for (const c of component) {
if (c.id === ComponentID.DEPENDENCY) {
const dependencies = (c as DependencyComponent).dependencies
for (const d of dependencies) {
for (const l of d.licenses) {
licenses.add(l.spdx_id)
}
}
}

if (c.id === ComponentID.FILE || c.id === ComponentID.SNIPPET) {
for (const l of (c as ScannerComponent).licenses) {
licenses.add(l.name)
}
}
}
}

return Array.from(licenses)
}
Loading

0 comments on commit dc762bf

Please sign in to comment.