Skip to content
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
13 changes: 9 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ contain the scanner, only a thin Docker container action that runs the published

## Versioning and releases

- The wrapped Provenant version is selected by the `FROM` tag in the `Dockerfile`, **not** by a
call-time input (GitHub Actions forbids expressions in a container action's image reference).
- Cutting an action release: bump the `Dockerfile` `FROM` tag to a concrete, working Provenant
version, tag `vX.Y.Z`, and move the floating `vX` tag. Consumers pin `@vN` or a full SHA.
- The `Dockerfile` is `FROM ghcr.io/getprovenant/provenant:latest`, so the action **auto-tracks the
newest Provenant release** — GitHub rebuilds the image on each run and pulls `:latest`. There is
**no per-Provenant-release commit or re-release of this action**; publish it once and it follows
Provenant forward.
- Cut an action release only for changes to the **action itself** (inputs, entrypoint, docs): tag
`vX.Y.Z` and move the floating `vX` tag. Consumers pin `@vN` or a full SHA.
- Trade-off: `@vN` is not pinned to a fixed scanner version. If reproducible version pinning is ever
needed without per-release commits, convert to a composite action running
`docker run …:${{ inputs.version }}` (default `latest`).
58 changes: 45 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,39 @@ jobs:
args: --license --package --copyright
```

### Fail the build on a disallowed license

Provide a [license-policy file](https://github.com/getprovenant/provenant/blob/main/docs/CLI_GUIDE.md#the-license-policy-file)
that marks licenses with a `compliance_alert`, then gate on it. The job fails
when a matching license is found, and the SARIF file surfaces the violations as
pull-request and code-scanning alerts:

```yaml
permissions:
contents: read
security-events: write # to upload SARIF

jobs:
license-gate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: getprovenant/provenant-action@v1
with:
license-policy: .github/license-policy.yml
fail-on: error
sarif-file: provenant.sarif
- uses: github/codeql-action/upload-sarif@v3
if: always() # upload findings even when the gate fails the job
with:
sarif_file: provenant.sarif
```

### Other scan options

Any `provenant scan` flag can be passed through `args` — for example
`--ignore "node_modules/*"` to skip noise, `--incremental` with a cached
`--cache-dir` to reuse work across runs, or `--license-policy policy.yml` for
policy-aware review. See the [CLI Guide](https://github.com/getprovenant/provenant/blob/main/docs/CLI_GUIDE.md)
`--ignore "node_modules/*"` to skip noise or `--incremental` with a cached
`--cache-dir` to reuse work across runs. See the [CLI Guide](https://github.com/getprovenant/provenant/blob/main/docs/CLI_GUIDE.md)
for the full set of workflows and flags.

## Inputs
Expand All @@ -86,11 +113,15 @@ for the full set of workflows and flags.
| `output-file` | `-` | Where to write the report. `-` streams to stdout (the workflow log); any other value is a path written inside the workspace. |
| `args` | `--license --package` | Extra raw arguments appended verbatim to `provenant scan`. Detections are opt-in — this is where you enable them (`--license`, `--package`, `--copyright`, `--info`, `--email`, `--url`, …). |
| `paths-file` | _(empty)_ | Optional file listing exact files/directories to scan (one per line), relative to a single scan root in `paths`. Ideal for pull-request CI via `git diff --name-only`. When set, `paths` must stay a single root (the default `.`). |
| `license-policy` | _(empty)_ | Optional path to a YAML license-policy file. Enables policy evaluation; required by `fail-on` and by SARIF output. |
| `fail-on` | _(empty)_ | Fail the job (exit 3) when a file matches a policy whose `compliance_alert` is at or above this level: `error` or `warning`. Requires `license-policy`. |
| `sarif-file` | _(empty)_ | Also write SARIF 2.1.0 of policy violations to this path, for `github/codeql-action/upload-sarif`. Meaningful only with `license-policy`. |

Under the hood the action runs:

```sh
provenant scan <paths> [--paths-file <paths-file>] --<output-format> <output-file> <args>
provenant scan <paths> [--paths-file <paths-file>] [--license-policy <file>] \
[--fail-on <level>] [--sarif <sarif-file>] --<output-format> <output-file> <args>
```

## Outputs
Expand All @@ -101,17 +132,18 @@ reading the report streamed to the workflow log when `output-file` is `-`.

## Versioning

The action is a Docker container action. The wrapped Provenant version is baked
into the action's [`Dockerfile`](Dockerfile) per release, so the version you run
is determined by the git ref you pin:
The action always runs the **latest** published Provenant release: its
[`Dockerfile`](Dockerfile) is `FROM ghcr.io/getprovenant/provenant:latest`, rebuilt on each run.
So the wrapped scanner advances automatically with every Provenant release — there is no per-release
update to this action.

You pin the **action's own** behavior by git ref:

- A **major version tag** (such as `@v1`) tracks the latest release within that
major series — the best default for most workflows.
- A **full commit SHA** is an exact, immutable pin.
- A **major version tag** (such as `@v1`) — the best default; picks up action fixes within that major.
- A **full commit SHA** — an exact, immutable pin of the action.

Because GitHub Actions does not allow expressions in a container action's image
reference, the wrapped Provenant version cannot be selected at call time via an
input; it is selected by the action release you pin to.
Because the action tracks `:latest`, `@vN` does not pin a fixed scanner version. If you need a
reproducible scanner version, pin the container directly instead (`docker run ghcr.io/getprovenant/provenant:<version> scan …`).

## How it works

Expand Down
24 changes: 24 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,27 @@ inputs:
to scan `paths` directly.
required: false
default: ""
license-policy:
description: >-
Optional path to a YAML license-policy file (see the Provenant CLI guide for
the format). Enables policy evaluation; required by `fail-on` and by SARIF
output.
required: false
default: ""
fail-on:
description: >-
Fail the job (exit code 3) when a scanned file matches a policy whose
compliance_alert is at or above this level: "error" or "warning". Requires
`license-policy`. Leave empty to report without gating.
required: false
default: ""
sarif-file:
description: >-
Optional path to also write SARIF 2.1.0 of policy violations, for uploading
with github/codeql-action/upload-sarif so findings appear as pull-request and
code-scanning alerts. Meaningful only with `license-policy`.
required: false
default: ""

# The upstream image (gcr.io/distroless/static-debian12) ships no shell and its
# ENTRYPOINT is the provenant binary itself, so optional/variadic inputs cannot
Expand All @@ -66,3 +87,6 @@ runs:
- ${{ inputs.output-file }}
- ${{ inputs.args }}
- ${{ inputs.paths-file }}
- ${{ inputs.license-policy }}
- ${{ inputs.fail-on }}
- ${{ inputs.sarif-file }}
17 changes: 17 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,19 @@
# $3 = output-file ("-" for stdout, or a path)
# $4 = extra args (raw flags, word-split intentionally)
# $5 = paths-file (optional; a --paths-file list, empty to skip)
# $6 = license-policy (optional; a --license-policy file, empty to skip)
# $7 = fail-on (optional; error|warning, empty to skip)
# $8 = sarif-file (optional; a --sarif output path, empty to skip)
set -eu

paths="${1:-.}"
fmt="${2:-json-pp}"
outfile="${3:--}"
extra="${4:-}"
pathsfile="${5:-}"
policy="${6:-}"
failon="${7:-}"
sariffile="${8:-}"

case "$fmt" in
json | json-pp | json-lines | yaml | cyclonedx | cyclonedx-xml | spdx-tv | spdx-rdf | debian | html)
Expand All @@ -37,6 +43,17 @@ set -- scan $paths
if [ -n "$pathsfile" ]; then
set -- "$@" --paths-file "$pathsfile"
fi
# License policy, the CI gate, and SARIF output. `--fail-on` and SARIF both need a
# policy to be meaningful; the CLI validates the `--fail-on` requirement.
if [ -n "$policy" ]; then
set -- "$@" --license-policy "$policy"
fi
if [ -n "$failon" ]; then
set -- "$@" --fail-on "$failon"
fi
if [ -n "$sariffile" ]; then
set -- "$@" --sarif "$sariffile"
fi
# shellcheck disable=SC2086
set -- "$@" "$fmt_flag" "$outfile" $extra

Expand Down