Repository navigation
ci(deps): bump super-linter/super-linter from 8.7.0 to 9.0.0 #58
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- | |
| # This workflow uses actions that are not certified by GitHub. | |
| # They are provided by a third-party and are governed by | |
| # separate terms of service, privacy policy, and support | |
| # documentation. | |
| # A sample workflow which sets up periodic OSV-Scanner scanning for vulnerabilities, | |
| # in addition to a PR check which fails if new vulnerabilities are introduced. | |
| # | |
| # For more examples and options, including how to ignore specific vulnerabilities, | |
| # see https://google.github.io/osv-scanner/github-action/ | |
| name: "OSV Scanner - PR" | |
| on: | |
| pull_request: | |
| branches: ["main"] | |
| workflow_dispatch: | |
| permissions: {} | |
| jobs: | |
| osv-scanner-pr: | |
| permissions: | |
| # Require writing security events to upload SARIF file to security tab | |
| security-events: write | |
| # Read commit contents | |
| contents: read | |
| # Actions read-only | |
| actions: read | |
| uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable-pr.yml@a345acffa64b0eaede81a3d9aae6141214d9c8fc" # v2.6.0 | |
| with: | |
| fail-on-vuln: false | |
| check: | |
| runs-on: ubuntu-latest | |
| needs: osv-scanner-pr | |
| steps: | |
| # The results are read from the uploaded artifacts rather than from the | |
| # reusable workflow's job outputs: a large output passed to a step via | |
| # env (or inline) exceeds the kernel's per-string exec limit and the | |
| # runner fails to start bash with "Argument list too long". | |
| - name: Download OSV scan results | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| pattern: "*-json-results" | |
| merge-multiple: true | |
| path: ${{ runner.temp }}/osv | |
| - name: Check OSV scan results | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| IFS=$'\n\t' | |
| # Print the vulnerabilities present in the new results but absent | |
| # from the old results (by id or alias), i.e. introduced by the PR, as | |
| # a table like the one from osv-scanner's reporter, with the columns | |
| # the results give directly; print nothing if there are none. A jq | |
| # failure (e.g. malformed results) aborts the step via set -e | |
| # instead of being mistaken for "no new vulnerabilities". | |
| old="${RUNNER_TEMP}/osv/old-results.json" | |
| new="${RUNNER_TEMP}/osv/new-results.json" | |
| # The scanner exits successfully without writing results when it | |
| # finds no lockfiles (a failed scan without results already fails | |
| # the reusable workflow), so a missing file means nothing was | |
| # scanned: no new results means nothing to check, and no old | |
| # results means every new vulnerability is introduced by the PR. | |
| if [ ! -e "${new}" ]; then | |
| echo "::notice::No OSV scan results for this PR (no lockfiles found), nothing to check." | |
| exit 0 | |
| fi | |
| if [ ! -e "${old}" ]; then | |
| old=/dev/null | |
| fi | |
| table="$(jq -r --slurpfile old "${old}" ' | |
| def pad($w): . + ((" " * ($w - length)) // ""); | |
| def rating: | |
| if . == null or . == 0 then "Unknown" | |
| elif . >= 9 then "Critical" | |
| elif . >= 7 then "High" | |
| elif . >= 4 then "Medium" | |
| else "Low" end; | |
| def form($n; $one; $many): if $n == 1 then $one else $many end; | |
| ([ $old[0].results[]?.packages[]?.vulnerabilities[]? | |
| | .id, .aliases[]? ] | |
| | map({(.): true}) | add // {}) as $known | |
| | [ .results[]? | |
| | (.source.path | ltrimstr("/github/workspace/")) as $source | |
| | .packages[]? | |
| | .package as $package | |
| | .groups[]? | |
| | select(any(.ids[]; $known[.] | not)) | |
| | { ids, | |
| cvss: (.max_severity // ""), | |
| ecosystem: $package.ecosystem, | |
| name: $package.name, | |
| version: $package.version, | |
| $source } ] | |
| | select(length > 0) | |
| | sort_by(.ecosystem, .source, .name, .version, .ids[0]) | |
| | . as $rows | |
| | ([ $rows[] | [.source, .name, .version] ] | unique | length) as $packages | |
| | ([ $rows[] | .ecosystem ] | unique | length) as $ecosystems | |
| | ([ $rows[] | .cvss | if . == "" then null else tonumber end | rating ] | |
| | group_by(.) | map({key: .[0], value: length}) | from_entries) as $ratings | |
| | [ ["OSV URL", "CVSS", "ECOSYSTEM", "PACKAGE", "VERSION", "SOURCE"] ] | |
| + [ $rows[] | [ (.ids | map("https://osv.dev/" + .) | join("\n")), | |
| .cvss, .ecosystem, .name, .version, .source ] ] | |
| | . as $table | |
| | [ range(6) as $c | [ $table[][$c] | split("\n")[] | length ] | max ] as $widths | |
| | ("+" + ([ $widths[] | "-" * (. + 2) ] | join("+")) + "+") as $border | |
| | def line($cells): "| " + ([ range(6) as $c | $cells[$c] | pad($widths[$c]) ] | join(" | ")) + " |"; | |
| def row($cells): | |
| ([ $cells[] | split("\n") | length ] | max) as $height | |
| | range($height) as $i | line([ $cells[] | split("\n")[$i] // "" ]); | |
| "Total \($packages) \(form($packages; "package"; "packages")) affected by \($rows | length) new \(form($rows | length; "vulnerability"; "vulnerabilities")) (\($ratings.Critical // 0) Critical, \($ratings.High // 0) High, \($ratings.Medium // 0) Medium, \($ratings.Low // 0) Low, \($ratings.Unknown // 0) Unknown) from \($ecosystems) \(form($ecosystems; "ecosystem"; "ecosystems")).", | |
| "", | |
| $border, row($table[0]), $border, ($table[1:][] | row(.)), $border | |
| ' "${new}")" | |
| if [ -z "${table}" ]; then | |
| exit 0 | |
| fi | |
| printf '\n%s\n' "${table}" | |
| echo "::error::PR introduces one or more new vulnerabilities; see the table above. For more details, such as fixed versions, see the 'Run osv-scanner-reporter' step of the 'osv-scanner-pr / osv-scan' job in this run." | |
| exit 1 |