---
title: GitHub Action
description: The recommended install path — every input, every output, and how to make the verdict block a merge.
order: 10
---

# GitHub Action

The Action installs `@izri/cli`, runs the scope check, optionally triggers a test run, and reports the result. It is a composite action — no JavaScript bundle, just bash — so it adds a few seconds to a workflow, not a build step.

```yaml
name: izri
on:
  pull_request:
    branches: [main]

jobs:
  izri:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: legendify-dev/izri/apps/github-action@v1
        with:
          api-token: ${{ secrets.IZRI_API_TOKEN }}
```

## `fetch-depth: 0` is required

The scope check diffs your head against `origin/<base>`. A shallow clone — the `actions/checkout` default — has no base ref to resolve, so the check fails before it starts. Either set `fetch-depth: 0` or fetch the base ref explicitly.

## Inputs

| Input | Required | Default | What it does |
| --- | --- | --- | --- |
| `api-token` | yes | — | Your Izri API token. Starts with `izri_`. Store it as a repository secret, never inline. |
| `api-url` | no | `https://api.izri.ai` | Override for self-hosted installs. |
| `project-id` | no | *(auto)* | Project ULID. When omitted the CLI resolves it from your git `origin` remote. |
| `mode` | no | `both` | `scope`, `tests`, or `both`. |
| `base-ref` | no | *(auto)* | Git base to diff against. Resolves to `origin/${{ github.base_ref }}` on pull requests and `origin/<default-branch>` on pushes. |
| `wait-for-results` | no | `true` | When `mode` includes tests, block until the run reaches a terminal status. |
| `fail-on-finding` | no | `true` | Exit non-zero on hard scope findings or a non-passing test run. |
| `cli-version` | no | `latest` | Version range for `@izri/cli`. Pin to a tag for reproducible CI. |

### Choosing a `mode`

- **`scope`** is deterministic and fast. No test run, no waiting. Good as a required check on every PR.
- **`tests`** triggers a run and (by default) waits for it.
- **`both`** is the default and what you want unless you have a reason otherwise.

### Pin `cli-version` for reproducibility

`latest` means a CLI release can change your CI behavior without a commit in your repository. Pin it once you're past evaluation:

```yaml
with:
  api-token: ${{ secrets.IZRI_API_TOKEN }}
  cli-version: '0.1.0'
```

## Outputs

| Output | Value |
| --- | --- |
| `scope-alignment-score` | Alignment score 0–100. Empty string when `mode=tests`. |
| `scope-findings-count` | Total scope findings, all severities. Empty string when `mode=tests`. |
| `scope-hard-findings-count` | Findings at `severity: error` — the only category that blocks by default. |
| `test-run-id` | The Izri test-run identifier. Empty string when `mode=scope`. |

Outputs are empty strings, not zeros, when their mode didn't run. Test for emptiness before doing arithmetic:

```yaml
      - uses: legendify-dev/izri/apps/github-action@v1
        id: izri
        with:
          api-token: ${{ secrets.IZRI_API_TOKEN }}

      - name: Comment when alignment is low
        if: steps.izri.outputs.scope-alignment-score != '' &&
            fromJSON(steps.izri.outputs.scope-alignment-score) < 60
        run: echo "Scope alignment is ${{ steps.izri.outputs.scope-alignment-score }}"
```

## Making the verdict binding

Until you require it, the check reports but enforces nothing.

**Settings → Branches → Branch protection rules → Require status checks to pass**, then add `izri/quality`.

Require the umbrella, not the individual signals. The umbrella already aggregates them and handles skipped signals correctly; requiring `izri/visual` directly would block every backend-only PR, because that signal legitimately skips when no UI route changed.

## Non-blocking evaluation mode

To surface findings without failing anyone's build while you evaluate:

```yaml
with:
  api-token: ${{ secrets.IZRI_API_TOKEN }}
  fail-on-finding: false
```

The check still publishes and the sticky comment still appears — the workflow just won't go red.

## Related

- [CLI](/docs/install/cli) — the same checks from your terminal.
- [Verdicts and exit codes](/docs/reference/verdicts-and-exit-codes) — what the Action's exit status means.
- [`.izri/scope.yml`](/docs/configure/scope-yml) — tune what the scope signal considers sensitive.
