SonarQube CLI
Read-only command-line tool for inspecting a self-hosted SonarQube instance via af sonar. Intentionally companion-shaped to af bb pr — the same numeric PR id identifies both sides.
Setup
SonarQube uses its own bearer token. Atlassian and Bitbucket credentials are not interchangeable. Add the following to your project's .env:
SONAR_TOKEN— User token from<sonar>/account/security(required)SONAR_BASE_URL— Sonar instance URL (optional; falls back tosonar.host.urlinsonar-project.properties)
Project Key Resolution
Walks the same path sonar-scanner does:
--project <key>flag (highest priority)sonar.projectKeyinsonar-project.properties(walking up from cwd)
There is intentionally no af.json block for Sonar — the properties file is the canonical source of truth.
Quick Reference
Run bare af sonar (no subcommand) for the full command and flag reference. Note af sonar --help is intercepted by af's router and prints only a short stub.
af sonar pr <id>— Quality gate + top new issues + measures for a Bitbucket PRaf sonar pr— Same, auto-detecting the PR id from the current branch's open Bitbucket PRaf sonar pr <id> --issues— List every fetched new issue instead of the top 4af sonar pr <id> --json— Raw JSON for scriptingaf sonar gate— Quality gate status for the main branchaf sonar prs— All PRs known to SonarQube
Output Formats
- Default: colourised, indented terminal text — gate status, issues, key measures, and a dashboard link. Not Markdown; don't paste it into a PR comment expecting it to render.
- JSON: Add
--jsonfor raw SonarQube API responses
Issue Limits
af sonar pr always fetches one page of at most 100 new issues — there is no pagination. --issues changes only the rendering: it prints every issue on that page instead of the top 4. On a PR with more than 100 new issues, --issues shows the first 100, not all of them. Use the dashboard link for the true full list.
Exit Codes
af sonar pr and af sonar gate exit non-zero when the quality gate status is ERROR — safe to drop into shell scripts and CI as a gate.
0— GateOK(or command completed successfully)1— GateERROR, or a command error
Common Workflows
Check the gate on a PR you're reviewing
# Explicit PR id — same number as af bb pr get 42
af sonar pr 42
# Auto-detect from the current branch
git checkout feature/auth-rewrite
af sonar pr
See the new issues in full
# Default trims to the top 4 — pass --issues to print the whole fetched page (max 100)
af sonar pr 42 --issues
Gate the main branch
af sonar gate
# Exits 1 if the gate is red — wire into a deploy script
Browse all PRs SonarQube has analysed
af sonar prs
CI / script integration
# Block a deploy on red gate
if ! af sonar gate >/dev/null; then
echo "Sonar gate is red — refusing to deploy"
exit 1
fi
# Extract a specific measure with jq.
# `measures` is the raw /api/measures/component body, so the metrics live in
# .measures.component.measures[] as {metric, value} pairs — there is no .measures.new_coverage.
af sonar pr 42 --json | jq -r '.measures.component.measures[] | select(.metric=="new_coverage") | .value'
The --json payload for af sonar pr is {project, pullRequest, gate, issues, measures, dashboardUrl}, each of gate/issues/measures being the untouched SonarQube API response. af sonar gate --json prints the quality gate response on its own (.projectStatus.status), and af sonar prs --json the raw PR list.
PR Auto-Detection
af sonar pr (no id) uses the bundled Bitbucket client to find the current git branch's open PR. It returns distinct errors for:
- Zero PRs open for the branch
- Multiple open PRs (ambiguous)
- Missing Bitbucket credentials
- Detached
HEAD
Each error message suggests af sonar pr <id> as the explicit escape hatch. Auto-detection requires the same BITBUCKET_* env vars as the bitbucket skill.
Tips
- Pair with
af bb pr get <id>— same numeric id, complementary views (code review vs. quality gate) --issuesfor full noise — the trimmed default is for at-a-glance review; reach for--issueswhen triaging, remembering the 100-issue page cap- Exit codes are scriptable —
af sonar pr 42 && echo ok || echo redis idiomatic - No mutations — this command is read-only by design; issue assign/transition and hotspot management are deferred
Out of Scope
The following are intentionally not part of af sonar:
- SonarCloud support (self-hosted SonarQube only)
- Mutating operations (issue assign, transition, hotspot review)
- Scanner wrapping (
sonar-scanneris invoked separately, typically in CI) - Inline Sonar gate status in
af bb proutput
Error Handling
- Without
--json: errors print to stderr as red text - With
--json: config errors, PR auto-detection failures, and SonarQube API errors are emitted as{"error": "message"}on stdout instead — so redirecting stdout captures them, and2>/dev/nullwill not suppress them. Parse the JSON for.errorrather than assuming a successful payload. - Argument-parse errors (an unknown flag, or
--projectwith no value) and an unknown subcommand ignore--jsonand always print plain text to stderr - Exit codes:
0success / gate OK,1error / gate ERROR (in every error case above)