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.
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 with the tests:run and tests:read scopes. 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, both, upload, or verify. |
junit-file |
with upload |
— | JUnit XML your test step produced. |
coverage-file |
no | — | LCOV or Cobertura report, for diff coverage. |
coverage-format |
no | (from extension) | lcov or cobertura. |
skipped-reason |
no | — | With upload, records an explicit empty run instead of results. |
test-command |
with verify |
— | Shell command that runs {files} (the selected test files, shell-quoted) and writes JUnit XML to {junit}. |
max-test-files |
no | 50 |
With verify: budget. Over it only the PR's changed test files run; still over, a budget skip is recorded. |
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
scopeis deterministic and fast. No test run, no waiting. Good as a required check on every PR.teststriggers a run on Izri's runner and (by default) waits for it. Playwright projects only.uploadsends the JUnit and coverage your own test step produced. This is the usual choice: most teams already run tests in CI, and Izri judges that run instead of repeating it. Give the jobpermissions: id-token: write(andcontents: read, since naming any permission drops the defaults): the CLI sends the job's id-token with the upload, and that is what lets Izri trust the evidence. Without it the upload is recorded as untrusted. Seeizri/tests.jobs: tests: runs-on: ubuntu-latest permissions: contents: read id-token: write steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - run: pnpm test -- --reporter=junit --outputFile=junit.xml continue-on-error: true - uses: legendify-dev/izri/apps/github-action@v1 with: api-token: ${{ secrets.IZRI_API_TOKEN }} mode: upload junit-file: junit.xmlverifyruns the revert check withizri verify. It runs the test files that depend on the change at head, and again with the changed source files restored to the merge base, each in a throwaway git worktree. Then it uploads both results forizri/hallucination. They are judged against theizri/testsevidence for the same commit, so add it next to anuploadstep (or keep the Izri runner). Install dependencies first, and give the job the sameid-token: writepermission.- run: pnpm install --frozen-lockfile - uses: legendify-dev/izri/apps/github-action@v1 with: api-token: ${{ secrets.IZRI_API_TOKEN }} mode: verify test-command: pnpm vitest run {files} --reporter=junit --outputFile={junit}bothis 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:
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. |
verification-run-id |
With verify: the recorded revert check. Empty string otherwise, or when it was not recorded. |
Outputs are empty strings, not zeros, when their mode didn't run. Test for emptiness before doing arithmetic:
- 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 (the single check run whose conclusion is the izri/quality verdict).
There is only one check to require. Izri carries the aggregated izri/quality verdict, which already handles skipped signals — visual legitimately skips when no UI route changed, and the verdict accounts for that. If you previously required izri/quality (or any izri/… child check), replace it with Izri; those contexts are no longer reported and a rule pinning them would block every merge.
Non-blocking evaluation mode
To surface findings without failing anyone's build while you evaluate:
with:
api-token: ${{ secrets.IZRI_API_TOKEN }}
fail-on-finding: falseThe check still publishes and the sticky comment still appears — the workflow just won't go red.
Related
- CLI — the same checks from your terminal.
- Verdicts and exit codes — what the Action's exit status means.
.izri/config.yml— tune what the scope signal considers sensitive.
Reading this with an agent? /docs/install/github-action.md serves the raw markdown.
Edit this page on GitHub →All docs