Goal
Run a SCANOSS scan on every pull request. Fail the check when the change contains open source code that your project’sscanoss.json does not approve yet, and keep the full result as a build
artefact.
When to use it
- You want to catch copied or vendored open source code before anyone merges it.
- You already have a CI system and want SCANOSS as one more check in it.
- You approve components through code review of
scanoss.json(see Approve components with scanoss.json).
Prerequisites
- A Linux x86-64 CI runner with
bash,git,curl,jq, andsha256sum SCANOSS_API_KEYavailable to the job as a secret environment variable- The pull request’s target branch available in the checkout, with enough history to find the merge base (a full clone is simplest)
scanoss/unapproved.jqcommitted to the repository (see Approve components)
The script
Save this asci/scanoss-pr.sh in your repository and make it executable
(chmod +x ci/scanoss-pr.sh).
What each step does
- Install. Downloads a pinned scanoss-cli release, checks it against the published
checksums.txt, and puts it on thePATH. It goes into a temporary directory so a full scan does not fingerprint the binary. - Choose the target. In
changedmode,git difflists the files the pull request adds or modifies compared to the merge base withBASE_REF.git checkout-indexcopies exactly those files into a temporary directory with the same relative paths. The script leaves out deleted files, because they cannot bring in new code. Infullmode the script scans the whole repository, which suits small repositories or a nightly job. - Settings. When the script scans the changed-files directory, the CLI cannot find the
repository’s
scanoss.jsonby itself, so the script passes it with--settings. Its BOM rules (approved components) and skip rules then apply. Because the copied files keep their relative paths, rules scoped to apathstill match. - Scan. The CLI fingerprints the files locally, uploads only the fingerprints, waits for the
result, and writes the raw inventory to
scanoss-results.json.--include licenses,vulnsadds licence and vulnerability data, so the same file can feed the licence and vulnerability gate. - Gate. The
unapproved.jqfilter lists every component detected in the code thatscanoss.jsondoesn’t approve. When a rule pins a version, it approves only that version. Any line in the list fails the check.
What the output means
A failing run prints one line per unapproved component:- The component is acceptable. Add it to
bom.identifyinscanoss.jsonin the same pull request, so reviewers see the change toscanoss.jsonin code review. - The match is not real, for example your own code that resembles a public project. Add a
bom.ignorerule for that component, scoped to the path if you can. - The code should not be there. Remove it from the pull request.
How it fails the pipeline
scanoss-cli itself always exits
0 after a successful scan, whatever it finds. The jq gate in
step 5 turns findings into a failure.
Run it in your CI system
All the logic is in the script. Your CI configuration only needs to check out the code with history, expose the secret, setBASE_REF, call the script, and keep scanoss-results.json. These two
examples show the pattern. The same steps work in any CI system.
- GitHub Actions
- GitLab CI
Variations
- Scan the whole repository on a schedule. Run the same script with
SCAN_MODE=fullfrom a nightly job. A full scan also re-checks files that did not change, for example after you remove an approval fromscanoss.json. - Use the container image instead of downloading the binary. Replace step 1 with
docker run --rm -v "$PWD:/src" -e SCANOSS_API_KEY ghcr.io/scanoss/scanoss:<version> scan /src .... See Using Docker for the output-permission caveat. - Speed up large scans. Raise
--threads, the number of fingerprint workers (default10).