Skip to content
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

Generate attribution report #53

Merged
merged 4 commits into from
Jan 22, 2025
Merged
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
9 changes: 9 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,12 @@ jobs:
api-key: ${{secrets.fossaApiKey}}
container: alpine:latest
run-tests: true

- name: Generate FOSSA report
id: example-generate-report
uses: ./
with:
api-key: ${{secrets.fossaApiKey}}
generate-report: json

- run: echo ${{ steps.example-generate-report.outputs.report }}
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,29 @@ jobs:
run-tests: true
```

## `generate-report`
**Optional** If set, FOSSA will run the `fossa report` command. Currently only the "attribution" (or "licensing") report is supported.

The value should be set to a [report format](https://github.com/fossas/fossa-cli/blob/master/docs/references/subcommands/report.md#specifying-a-report-format).

The report's content is set as an output. Write the output to a file as needed.

Example
```yml
jobs:
fossa-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- id: fossa
uses: fossas/fossa-action@main # Use a specific version if locking is preferred
with:
api-key: ${{secrets.fossaApiKey}}
run-tests: true
generate-report: html
- run: ${{ steps.fossa.outputs.report }} > report.html
```

## `test-diff-revision`
**Optional** If set to a string, FOSSA will run the `fossa test` command with the `--diff` [option](https://github.com/fossas/fossa-cli/blob/master/docs/references/subcommands/test.md#test-for-new-issues-compared-to-another-revision).

Expand Down
10 changes: 10 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ inputs:
Run fossa test with the `--diff <revision>` option, which checks if there are new issues relative to `<revision>`.
Requires `run-tests` to be set in order to take effect.
required: false
generate-report:
description: >-
If set, after analyzing your project, FOSSA will generate a report which is accessible from the `report` step output.
The value must be a [report format](https://github.com/fossas/fossa-cli/blob/master/docs/references/subcommands/report.md#specifying-a-report-format).
Currently only the attribution report is supported.
required: false

outputs:
report:
description: If `generate-report` is provided, this will contain the string contents of the report in the requested format.

runs:
using: node20
Expand Down
6 changes: 3 additions & 3 deletions dist/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ export const PROJECT = getInput('project', getInputOptions());
export const TEAM = getInput('team', {required: false});
export const POLICY = getInput('policy', {required: false});
export const DEBUG = getBooleanInput('debug', {required: false});
export const REPORT_FORMAT = getInput('generate-report', getInputOptions());
62 changes: 57 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { error, setFailed } from '@actions/core';
import { exec } from '@actions/exec';
import { error, setFailed, setOutput } from '@actions/core';
import { exec, ExecListeners } from '@actions/exec';
import {
CONTAINER,
FOSSA_API_KEY,
Expand All @@ -11,12 +11,14 @@ import {
TEAM,
POLICY,
DEBUG,
REPORT_FORMAT,
} from './config';
import { fetchFossaCli } from './download-cli';

// Github doesn't always collect exit codes correctly, so we check output
const failedRegex = /(A fatal error occurred|Test failed\. Number of issues found)/;

export async function analyze(): Promise<void> {
// Github doesn't always collect exit codes correctly, so we check output
const failedRegex = /(A fatal error occurred|Test failed\. Number of issues found)/;
const getEndpointArgs = (): string[] => !ENDPOINT ? [] : [
'--endpoint',
ENDPOINT,
Expand Down Expand Up @@ -55,7 +57,7 @@ export async function analyze(): Promise<void> {
output += data.toString();
};

const listeners = {
const listeners: ExecListeners = {
stdout: collectOutput,
stderr: collectOutput,
};
Expand Down Expand Up @@ -89,6 +91,53 @@ export async function analyze(): Promise<void> {
}
}

export async function report(): Promise<void> {
const getEndpointArgs = (): string[] => !ENDPOINT ? [] : [
'--endpoint',
ENDPOINT,
];
const getProjectArgs = (): string[] => !PROJECT ? [] : [
'--project',
PROJECT,
];
const getFormatArgs = (): string[] => !REPORT_FORMAT ? [] : [
'--format',
REPORT_FORMAT,
];

const getArgs = (cmd: string) => [
cmd,
...getEndpointArgs(),
...getProjectArgs(),
...getFormatArgs(),
DEBUG ? '--debug' : null,
].filter(arg => arg);

// Setup listeners
let output;
const collectOutput = (data: Buffer) => {
output += data.toString();
};

const listeners: ExecListeners = {
stdout: collectOutput,
stderr: collectOutput,
};

// Collect default options: Env and listeners
const PATH = process.env.PATH || '';
const defaultOptions = { env: { ...process.env, PATH, FOSSA_API_KEY }, listeners };
output = '';
const exitCode = await exec('fossa', [...getArgs('report attribution')], defaultOptions);

// Check output or exitCode
if (exitCode !== 0 || output.match(failedRegex)) {
throw new Error(`FOSSA failed to scan`);
}

setOutput('report', output);
}

async function run() {
try {
await fetchFossaCli();
Expand All @@ -98,6 +147,9 @@ async function run() {

try {
await analyze();
if(REPORT_FORMAT?.length) {
await report();
}
} catch (e) {
setFailed(e);
}
Expand Down
Loading