Skip to content

CLI reference

All three GitHub surfaces drive the same brimyr CLI. Exit codes: 0 pass · 1 patch coverage below threshold, or blocking net-new quality findings · 2 broken test run / setup / usage error, a quality input the gate could not evaluate, or a quality scan that did not complete. A run that does both halves exits with the worse of the two.

brimyr <coverage | ci | local | lint | version> [options]

brimyr coverage

The pure patch-coverage computation: coverage file(s) + a base/head → patch coverage % + a gate exit code. Runs no tests, so it's decoupled from any toolchain and unit-tested in isolation.

brimyr coverage --coverage-file coverage.xml --base "$BASE" \
    --threshold 80 --json-out coverage.json
Flag Default Purpose
--coverage-file (required) Coverage file path[:format] (lcov|cobertura|jacoco; inferred from the extension, and .xml is resolved by its root element). Repeatable.
--base (required) Base ref/SHA (PR target).
--head HEAD Head ref/SHA.
--repo . Path to the git repository.
--threshold 80 Patch-coverage % that blocks below it.
--strip-prefix none Path prefix to strip from coverage paths before matching (repeatable).
--min-lines 20 Skip the threshold when the diff has fewer changed executable lines than this. 0 gates every diff.
--exclude none Glob whose matching changed files leave the denominator entirely (repeatable). * crosses /.
--no-merge-base off Diff base..head directly instead of merge-base(base, head)..head.
--json-out none Write the patch-coverage summary as JSON.
--no-gate off Always exit 0 (report only).
--quiet off Suppress the human summary.

brimyr ci

The full CI flow: detect the ecosystem(s), run the right test command with coverage, gate on patch coverage (PR events), and run sonar-scanner (non-blocking). Given the quality flags it decides the net-new quality half as well, and renders both verdicts into one summary and one comment.

brimyr ci --mode auto --sonar-url https://sonar.example.com --sonar-project-key my-svc

Key flags beyond the shared options:

Flag Default Purpose
--mode auto auto (from GITHUB_EVENT_NAME), pr (gate), or baseline (no gate).
--coverage-file none Escape hatch: ingest a pre-made report instead of running tests. Repeatable.
--ecosystem none Force python|javascript|dotnet|java instead of auto-detect. Repeatable.
--test-command none Override the detected test command (a shell command string).
--sonar-url none SonarQube host URL (enables the non-blocking scanner run).
--sonar-token-env SONAR_TOKEN Env var holding the Sonar token.
--sonar-project-key / --sonar-organization none Sonar targeting.
--sonar-sources . sonar.sources value.
--sonar-arg none Extra raw sonar-scanner arg, e.g. -Dsonar.foo=bar (repeatable).
--html-report none Directory for a browsable HTML coverage report. Needs ReportGenerator; never affects the gate.

PR comment flags

Also accepted by brimyr local and brimyr lint, though they only do anything when there is a PR to comment on and a token to comment with. All of them are non-blocking: nothing here can change the exit code. See PR comment for the full behaviour.

Flag Default Purpose
--pr-comment off Post/update the single comment on the PR — consolidated (coverage plus the quality block, when that half ran) on ci and local; quality only on lint, under its own marker.
--pr-number from the event PR number (read from $GITHUB_EVENT_PATH otherwise).
--repo-slug $GITHUB_REPOSITORY owner/repo being commented on.
--github-token-env GITHUB_TOKEN Env var holding the comment token; needs pull-requests: write.
--token-broker-url none Broker base URL. Authors as Brimyr[bot]; falls back silently to the token above on any failure. Needs id-token: write.
--github-api-url $GITHUB_API_URL, else api.github.com GitHub API base (GitHub Enterprise).

Quality flags

Also accepted by brimyr local. Supplying either --quality-counts or --quality-scan-broken turns the quality half on: Brimyr reads what chargate filter-sarif left behind — or, for a scan that did not complete, reads nothing and says so — decides pass/fail on its own threshold, and renders that verdict into the same summary and the same PR comment as coverage. One consolidated view is the reason to prefer this over the standalone brimyr lint. The process exit code becomes the worse of the two halves.

Flag Default Purpose
--quality-counts none Chargate's filter-sarif --counts-json output. The verdict's only input; supplying it turns the quality half on.
--quality-findings none Chargate's filter-sarif --out net-new SARIF. Read only to list findings in the summary; a result count that contradicts the counts JSON is a hard error (exit 2).
--quality-fail-on none SARIF level at or above which a net-new finding blocks: none (report only), note, warning, error, any.
--quality-scan-broken off The scan did not complete. Turns the quality half on, reads no file at all, and reports a tool error (exit 2, quality_gate_result error) — the counts file a failed scan leaves behind is a row of zeros, which is what a clean PR looks like.
--quality-scan-note none Linters the scan could not run, stated in the summary next to the count. A completed scan is not necessarily a full one. Never blocks.
--quality-json-out none Write the quality summary as JSON here.

brimyr local

Run the gate against a locally inferred base (the repo's default branch) to check a branch before pushing. Same flags as ci — including the quality and PR-comment ones — plus an optional --base to override the inferred base. In practice it is the coverage half you run locally, since the quality half needs Chargate's output.

brimyr local                 # detect, run tests, gate vs the default branch
brimyr local --base main

brimyr lint

Gate on the net-new quality findings Chargate already classified. Brimyr does not import, vendor or re-implement that engine — it reads the two files chargate filter-sarif writes and decides on them. Chargate reports, Brimyr gates. Runs no linter and parses no diff.

brimyr lint --counts chargate-reports/counts.json \
    --findings chargate-reports/net-new.sarif --fail-on error
Flag Default Purpose
--counts none Chargate's filter-sarif --counts-json output. The gate's only input. Required unless --scan-broken says there is nothing worth reading.
--findings none Chargate's filter-sarif --out net-new SARIF. Read only to list findings in the summary; a result count that contradicts --counts is a hard error (exit 2).
--fail-on none SARIF level at or above which a net-new finding blocks: none (report only), note, warning, error, any.
--no-gate off Always exit 0 (report only).
--scan-note none Linters the scan could not run, stated in the summary next to the count. A completed scan is not necessarily a full one. Never blocks.
--scan-broken off The quality scan did not complete. Skips every read and reports a tool error (exit 2) — the counts file a failed scan leaves behind is a row of zeros, which is what a clean PR looks like.
--json-out none Write the quality summary as JSON here.
--quiet off Suppress the human summary.

The threshold speaks SARIF levels and not Chargate's severity bands. Chargate gates on per-result verdicts, where a missing security-severity falls back to the level, so its bands work. Brimyr reads only the counts document, whose per_severity_* maps are populated solely from a real security-severity — a property quality linters essentially never emit — so a band-valued threshold read off it would match nothing on every PR. error is the equivalent of Chargate's fail_on: high, and any blocks on every net-new finding including the ones its linter left unlevelled.

It also takes the PR comment flags, and comments under its own marker: the two subcommands can run in either order, or only one of them, so sharing a marker would mean whichever ran last erased the other's verdict. Two comments is the cost of running the halves separately.

Exit codes are the coverage gate's: 0 pass · 1 blocking net-new findings · 2 an input it could not read, a schema_version it does not recognise, counts that contradict themselves, or --scan-broken. A gate that cannot evaluate its input never goes green.

brimyr version

Prints the brimyr version (also brimyr --version).