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 committed Jan 22, 2024
1 parent 73dbc23 commit b984014
Show file tree
Hide file tree
Showing 9 changed files with 288 additions and 32 deletions.
23 changes: 10 additions & 13 deletions .github/workflows/test-action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,33 @@ 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: 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
run: cat "${{ steps.test-action.outputs.result-filepath }}"
run: echo "${{ steps.test-action.outputs.licenses }}"
2 changes: 1 addition & 1 deletion .prettierrc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"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()
})
})
86 changes: 86 additions & 0 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.
7 changes: 6 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
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.
Expand All @@ -24,11 +25,15 @@ export async function run(): Promise<void> {

// run scan
await exec.exec(
'scanoss-py',
'docker run -it ghcr.io/scanoss/scanoss-py:v1.9.0',
['scan', repoDir, '--output', outputPath],
options
)

const scannerResults = await readResult(outputPath)
const licenses = getLicenses(scannerResults)
core.setOutput('licenses', licenses.toString())

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

export enum ComponentID {
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[]
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
}
}
31 changes: 31 additions & 0 deletions src/services/result.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
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) {
const licenses = new Set<string>()

for (const [path, component] of Object.entries(results)) {
component.forEach(c => {
if (c.id === ComponentID.DEPENDENCY) {
;(c as DependencyComponent).dependencies.forEach(d => {
d.licenses.forEach(l => {
licenses.add(l.spdx_id)
})
})
}

if (c.id === ComponentID.FILE || c.id === ComponentID.SNIPPET) {
;(c as ScannerComponent).licenses.forEach(l => {
licenses.add(l.name)
})
}
})
}

return Array.from(licenses)
}
52 changes: 52 additions & 0 deletions src/services/result.test.ts

Large diffs are not rendered by default.

0 comments on commit b984014

Please sign in to comment.