docs(skill): add sonarqube cleanup + inspection skill
Codifies (A) how to query the bermudalamb SonarQube 9.9 server's web API from PowerShell — Basic auth with token-as-username, the SONARQUBE_URL trailing-slash gotcha, the useful endpoints for triage and Won't Fix transitions; and (B) the per-rule-group cleanup loop (query → pick → edit → build → test → commit → scan → verify). References memory sonarqube-wontfix-rules rather than duplicating the catalog. Frontmatter follows superpowers:writing-skills (description is triggering conditions only, no workflow summary). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
71cdf8a766
commit
d92996bd2e
@@ -0,0 +1,66 @@
|
||||
---
|
||||
name: sonarqube
|
||||
description: Use when working with SonarQube tech debt in this repo — querying the bermudalamb 9.9 server's web API from PowerShell, triaging open issues for the sql-utilities project, running scan-sonar.ps1 and verifying net-down after a cleanup commit.
|
||||
---
|
||||
|
||||
# Sonarqube (sql-utilities)
|
||||
|
||||
## Overview
|
||||
|
||||
Two halves: **(A)** how to inspect the server from a PowerShell prompt, and **(B)** the per-rule-group cleanup loop that keeps tech-debt fixes from introducing new warnings.
|
||||
|
||||
The repo has `SonarAnalyzer.CSharp` referenced in `Directory.Build.props`, so every `dotnet build` surfaces the same rule set the server reports — in the Error List / build output, not the SonarLint pane. Local build is the fast feedback loop; `scan-sonar.ps1` is what publishes results to the server.
|
||||
|
||||
## A — Inspecting the server
|
||||
|
||||
Server: `https://snrqbe.bermudalamb.synology.me` (9.9 LTS). Project key: `sql-utilities`.
|
||||
|
||||
Auth is **HTTP Basic with the token as the username and an empty password** — **not** Bearer (Bearer was added in 10.0 and returns 401 here).
|
||||
|
||||
```powershell
|
||||
$url = $env:SONARQUBE_URL.TrimEnd('/') # the env var is stored with a trailing /
|
||||
$tok = $env:SONARQUBE_TOKEN # squ_ user token, Windows user-scope
|
||||
$b64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("${tok}:"))
|
||||
$h = @{ Authorization = "Basic $b64" }
|
||||
|
||||
Invoke-RestMethod -Uri "$url/api/issues/search?componentKeys=sql-utilities&resolved=false&ps=500&facets=severities,types,rules" -Headers $h
|
||||
```
|
||||
|
||||
**Gotcha:** `SONARQUBE_URL` is stored with a trailing `/`. Without `TrimEnd('/')` you build `//api/...` and the server answers with the SPA HTML shell — `Invoke-RestMethod` happily returns it and downstream `.issues`/`.facets` access yields blank output silently.
|
||||
|
||||
**Useful endpoints:**
|
||||
- `/api/issues/search` — `?severities=MAJOR,MINOR`, `?rules=csharpsquid:S1168`, `?resolutions=WONTFIX`, `&facets=rules,severities,types` for triage views.
|
||||
- `/api/issues/add_comment` (POST: `issue`, `text`) — justification before a Won't Fix transition.
|
||||
- `/api/issues/do_transition` (POST: `issue`, `transition=wontfix`) — mark a known false-positive without changing code.
|
||||
- `/api/qualitygates/project_status?projectKey=sql-utilities` — current gate status.
|
||||
- `/api/measures/component?component=sql-utilities&metricKeys=code_smells,coverage,duplicated_lines_density,ncloc,sqale_index` — headline numbers.
|
||||
- `/api/ce/component?component=sql-utilities` — most-recent analysis task status (queued / in-progress / failed).
|
||||
|
||||
`SONARQUBE_URL` / `SONARQUBE_TOKEN` are read here; `scan-sonar.ps1` reads the separate `SONAR_TOKEN` / `SONAR_HOST_URL` for the *upload* path — do not conflate them.
|
||||
|
||||
## B — Cleanup loop
|
||||
|
||||
```dot
|
||||
digraph cleanup {
|
||||
query [label="Query open issues + facets"];
|
||||
pick [label="Pick one rule group"];
|
||||
edit [label="Edit code"];
|
||||
build [label="dotnet build -c Release"];
|
||||
test [label="dotnet test -c Release --no-build"];
|
||||
commit [label="git commit\nchore(sonar): … (Sxxxx)"];
|
||||
more [label="More groups?" shape=diamond];
|
||||
scan [label="scan-sonar.ps1"];
|
||||
verify [label="Query API: confirm net-down"];
|
||||
|
||||
query -> pick -> edit -> build -> test -> commit -> more;
|
||||
more -> pick [label="yes"];
|
||||
more -> scan [label="no"];
|
||||
scan -> verify;
|
||||
}
|
||||
```
|
||||
|
||||
1. **Query.** Start with `severities=MAJOR,MINOR` + `facets=rules` to see what's worth fixing.
|
||||
2. **Pick a rule group.** One Sxxxx (or one tightly-related cluster) per commit, easiest first so a late blocker doesn't strand the others.
|
||||
3. **Edit → build → test.** Build must succeed; the warning count for the touched rule must drop. Tests must stay green. If a fix would degrade clarity or break a tested contract, prefer **Won't Fix on the server with a justification** over a forced code change — see [[sonarqube-wontfix-rules]] for the catalog of rules already triaged that way (S1168, S3925, CS8601, S107).
|
||||
4. **Commit.** `chore(sonar): <one-line> (Sxxxx)` — bang (`!`) if it's a breaking rename.
|
||||
5. **After all groups:** `./scan-sonar.ps1` (needs `$env:SONAR_TOKEN`). Wait ~30-60s for the CE task to finish, then re-query the issues endpoint and confirm the open MAJOR/MINOR count fell by the expected number.
|
||||
|
||||
Reference in New Issue
Block a user