# Report formats and CI automation

> Export text, JSON, Markdown, or SARIF output and wire the scanner into local hooks or CI workflows.

Canonical: https://hol.org/guard/docs/plugin-scanner/report-formats-and-ci · Updated: 2026-10-23 · Applies to: Guard 3.x

`plugin-scanner` can emit human-readable summaries, machine-readable artifacts, and GitHub-friendly security reports from the same scan.

## Report formats

| Format | Best use |
| :--- | :--- |
| `text` | local terminal review with category totals and findings |
| `json` | structured integrations and dashboards |
| `markdown` | pull request or issue-ready summaries |
| `sarif` | GitHub code scanning uploads and security automation |

Examples:

```bash
plugin-scanner scan . --format text
plugin-scanner scan . --format json
plugin-scanner scan . --format markdown
plugin-scanner scan . --format sarif --output plugin-scanner.sarif
```

`--format` and `--output` belong to `scan`. `lint` and `verify` print `text` or `json` to the terminal. See [Policies, output, and trust provenance](https://hol.org/guard/docs/plugin-scanner/policies-and-output) for the JSON fields.

## Common gating flags

Fail CI when a finding crosses your severity floor, or when the score is too low:

```bash
plugin-scanner scan . --fail-on-severity high
plugin-scanner scan . --min-score 80
```

Both flags can be combined. `--strict` fails on any finding at all.

## Optional Cisco analysis

Cisco skill scanning needs Python 3.11 through 3.14 and the `cisco` extra:

```bash
pipx install 'plugin-scanner[cisco]'
plugin-scanner scan ./my-plugin --cisco-skill-scan on --cisco-policy strict
```

Cisco MCP analysis needs the separate `cisco-mcp` dependency group in a source checkout of the `hol-guard` repository, or the container image:

```bash
plugin-scanner scan ./my-plugin --cisco-mcp-scan on
```

Both flags default to `auto`. When an analyzer is not available, the report records its status and message under `summary.integrations` instead of failing the scan.

## Values to gate on

The JSON report carries `score`, `grade`, `policy_pass`, `summary.gradeLabel`, and `summary.findings`. The GitHub Action turns the same data into step outputs such as `score`, `grade`, `grade_label`, `policy_pass`, `verify_pass`, `max_severity`, and `findings_total`. Pick one of them as your gate so review, registry ingestion, and release workflows all read the same value.

## CLI-first CI pattern

Use the CLI directly when you want the repository to control install, caching, and report upload. Pin an exact `plugin-scanner` version so the gate does not change between runs:

```yaml
permissions:
  contents: read
  security-events: write

jobs:
  scan-plugin:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-python@v7
        with:
          python-version: "3.13"
      - name: Install scanner
        run: pip install "plugin-scanner==<version>"
      - name: Scan plugin
        run: plugin-scanner scan . --format sarif --output plugin-scanner.sarif --fail-on-severity high
      - name: Upload SARIF
        if: always()
        uses: github/codeql-action/upload-sarif@v4
        with:
          sarif_file: plugin-scanner.sarif
```

Replace `<version>` with a released version from PyPI. For stricter supply-chain hygiene, pin each third-party action to a full commit SHA. The [GitHub Action](https://hol.org/guard/docs/plugin-scanner/github-action) does the install and SARIF upload for you, with hash-locked dependencies.

## Local pre-commit pattern

```yaml
repos:
  - repo: local
    hooks:
      - id: plugin-scanner
        name: Plugin Scanner
        entry: plugin-scanner scan . --fail-on-severity high
        language: system
        pass_filenames: false
        always_run: true
```

## Next guides

- [Policies, output, and trust provenance](https://hol.org/guard/docs/plugin-scanner/policies-and-output)
- [GitHub Action quality gate](https://hol.org/guard/docs/plugin-scanner/github-action)
- [Submission and registry payloads](https://hol.org/guard/docs/plugin-scanner/submission-and-registry-payloads)
