sonarqube-check · git:20260924.a457823 · 2026-09-24 · sha256 acf733d9ce663a37
sonarqube-check git:20260924.a457823A
Immutable. This exact content never changes and is served at /api/v1/blob/acf733d9ce663a37.
--- name: sonarqube-check description: | SonarQube quality gate, any language, no company server needed: run SonarQube Community Build locally (Docker), read the real gate + issues, fix by rule id, re-scan and diff. A linter's green build is a pre-check, never the gate. --- # SonarQube quality gate — produce the real report, locally <!-- routing-eval reads the next line; why it sits in the body: AGENT_TEMPLATE.md --> Trigger phrases: "sonarqube", "quality gate", "code smell", "sonar scan", "sonar rapor", "A rating" **Only a SonarQube analysis can say "rating A, 0 findings".** A clean `build` says the compiler was happy — a different claim, about a different rule set. Passing one off as the other is how a team is told the code is clean and then opens a report full of findings. You do **not** need a company server or someone else's token to get the real thing: **SonarQube Community Build is free, needs no licence key, and runs in one Docker container on this machine.** That is the default path here — the gate is produced locally, offline, and it is a genuine SonarQube verdict, not a proxy for one. Language-agnostic on purpose: SonarQube covers 20+ languages plus IaC (Terraform, Kubernetes, Dockerfile). Detect what the project actually uses; never assume a stack. ## Step 1 — get a real analysis (pick the first that applies) **a) The project already has a SonarQube** → use it, and skip to step 2. **b) It does not → stand one up locally.** Docker one-liner, the Docker-free server zip, the first login and the token: **`references/stand-up-server.md`**. No licence, no external account, nothing leaves the machine. > **Restarting is not installing.** Bringing an already-approved service back up on this machine — the same > image, the same volumes — is resuming what the user already said yes to, and this skill's own advice to keep > a named volume assumes exactly that. A NEW image, a new volume, or a tool this machine does not have is an > install, and needs the answer below. > > **Nothing here is installed without the user saying so.** Docker, Java, a scanner, a linter — each is a proposal > with its cost stated, and the user picks. If they decline all of them, that is a valid answer: go to (c) and > report "unverified" rather than installing anything to make a number appear. Scan with whatever runner the project's stack uses — the scanner is the same product for every language: | Project | Scan command | |---|---| | Any stack (generic) | `sonar-scanner -Dsonar.projectKey=app -Dsonar.sources=. -Dsonar.host.url=http://localhost:9000 -Dsonar.token=$T` | | Maven / Gradle | `mvn sonar:sonar -Dsonar.host.url=… -Dsonar.token=$T` · `gradle sonarqube …` | | .NET | `dotnet sonarscanner begin /k:app /d:sonar.host.url=… /d:sonar.token=$T` → `dotnet build` → `dotnet sonarscanner end /d:sonar.token=$T` | | JS/TS, Python, Go, PHP, Ruby | the generic `sonar-scanner` above (add coverage report paths if the project produces them) | **c) No server is possible at all** (no Docker, no Java, no permission to run one) → run the language's Sonar-rule engine locally as a pre-check (**`references/local-engines.md`** — which engine per language, and how close it is to Sonar's own rules) and **say what that is worth**, in these words rather than a rating: *"the local rule engine reports N issues, none open; the SonarQube rating and the gate were not produced — no analysis ran."* Then list what stays unverified: taint/injection, hotspot review state, coverage, duplication, files outside the compiled language, and the project's own quality profile. Offer branch (b) — a local server, with or without Docker — as the way to close it. **Never invent the verdict.** A rating exists only where an analysis produced one; without it the honest output is "unverified", and that is the sentence that saves the user from promising a clean report they cannot back. ## Step 2 — read the verdict, don't infer it ```bash S=http://localhost:9000; K=app # or the project's own host/key curl -sfu "$T:" "$S/api/qualitygates/project_status?projectKey=$K" # pass / fail, and which condition failed curl -sfu "$T:" "$S/api/issues/search?componentKeys=$K&resolved=false&ps=500" # rule id + file + line per finding curl -sfu "$T:" "$S/api/hotspots/search?projectKey=$K&status=TO_REVIEW" # hotspots are a SEPARATE endpoint curl -sfu "$T:" "$S/api/measures/component?component=$K&metricKeys=alert_status,bugs,vulnerabilities,security_hotspots,code_smells,coverage,duplicated_lines_density,reliability_rating,security_rating,sqale_rating" ``` Also read the gate's definition (`/api/qualitygates/show`): most gates judge **new code**, not the whole project. Chasing overall counts while the gate measures new code burns days and still fails; the reverse leaves real debt. Know which one applies before planning the work. ## Step 3 — fix by rule, never by impression Group findings by `rule` (`csharpsquid:S1481`, `typescript:S3776`, `python:S5852`, …) and take one rule at a time, all occurrences together. Read what the rule actually asks, fix the cause, cite the rule id in the change. The domain owner does the fixing — a security rule is `crew-security-expert`'s, a query/index rule is `crew-database-expert`'s. **Never close a finding by silencing it.** `#pragma warning disable`, `// NOSONAR`, `eslint-disable`, an exclusion in `sonar-project.properties` — each one changes the report without changing the code. It needs a written reason and the user's approval, every time. **Security Hotspots do not close by editing code.** Each is reviewed in the UI and marked *safe* (with a rationale) or *fixed*. Code changes alone leave it `TO_REVIEW` and the gate keeps failing. ## Step 4 — re-scan and diff. The loop is the deliverable Re-run step 1's scan, re-read step 2, and report the **difference**: counts before → after, which rule ids disappeared, which remain, which are new. "It should be clean now" is not a result — a second analysis is. Repeat until the gate says `OK`, or every remaining finding has a user-approved suppression. Nothing here closes on a first pass. ## What even a local SonarQube cannot see Community Build has no **taint/injection analysis** (data flow from user input to a dangerous sink — SQLi, XSS, command injection); that engine is in the paid editions. It also has no branch/PR analysis. So a clean local gate is not proof of injection safety: cover that with the **`security-scan`** and **`threat-model`** skills plus a `crew-security-expert` review, and say which of the two verdicts you are reporting. ## DoD - The verdict is quoted **from an analysis**: gate status, counts by severity, ratings, analysis date, and where it ran (project server or local container). - Every finding closed by a code change, or by a suppression the user explicitly approved with a written reason. - Hotspots reviewed in the UI, not merely edited around. - A re-scan ran after the fixes and the before → after diff by rule id is reported. - Injection risk stated separately (taint analysis is not in Community Build). - Anything not done is said plainly — never implied clean.