Files
sql-utilities/.claude/skills/sonarqube/SKILL.MD
T
Thom LambandClaude Opus 4.7 d92996bd2e 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>
2026-05-26 09:34:44 -05:00

4.1 KiB

name, description
name description
sonarqube 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 passwordnot Bearer (Bearer was added in 10.0 and returns 401 here).

$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

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.