Files
docs/ci/SONARQUBE.md
wtclaude ec468e9983 docs(ci): use the actual case-sensitive SonarQube project keys
link and Android-app reuse the pre-existing capitalised keys
(Runic-Gateway-link, Runic-Gateway-Android-app); the server rejects
case-variant duplicates. Note the case-sensitivity gotcha.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-20 23:21:04 -05:00

2.9 KiB

SonarQube static analysis

Each code repo in the Runic Gateway org reports static-analysis results to the self-hosted SonarQube server for review. Analysis is non-blocking: it runs on push to main (i.e. after merge), never on pull requests, so it never gates a PR. It complements each repo's PR gate and release pipeline — it only feeds the dashboard.

Server

  • URL: https://sonar.whitlocktech.com
  • Each repo is a separate SonarQube project, keyed as below.

Projects

Repo Project key Sources analysed Language
website runic-gateway-website server/src, client/src, bot/src JS/TS
link Runic-Gateway-link sidecar/src Rust
Android-app Runic-Gateway-Android-app app/src/main Kotlin

Project keys are case-sensitive and must match what already exists on the server — SonarQube refuses to create a key that differs only in case from an existing one. link and Android-app reuse the pre-existing capitalised keys above; website predates this note with its lower-case key.

How it's wired

Each repo carries two files, identical in shape across repos:

  • sonar-project.properties (repo root) — declares the project key, sources, tests, and exclusions. The Sonar scanner reads this.
  • .gitea/workflows/sonarqube.yml — a SonarQube workflow that, on push to main (and via manual workflow_dispatch), checks out with full history (fetch-depth: 0, needed for accurate blame + "new code") and runs sonarsource/sonarqube-scan-action@v4.

The scan is source-based — it does not build the project or run a language toolchain, so the workflows are lightweight (checkout + scan only). Richer signals (Rust Clippy, Android Lint, JaCoCo coverage) are left as documented, commented-out enrichment in each repo's sonar-project.properties; enable them per repo when wanted.

One-time setup per repo (Gitea UI → Repo → Settings → Actions)

Both are consumed by the scan action via env: in the workflow:

  • Secret SONAR_TOKEN — a SonarQube Analysis token (My Account → Security in SonarQube; project-scoped or global).
  • Variable SONAR_HOST_URL — the SonarQube base URL reachable from the self-hosted runner. Kept as a variable, not committed, so the internal address stays out of git.

The self-hosted ubuntu-latest runner must be able to reach SONAR_HOST_URL on the network. Nothing waits on the SonarQube Quality Gate, so a failing gate does not fail the job — check the dashboard.

Adding a new repo

  1. Create the project in SonarQube; note its key.
  2. Add sonar-project.properties (copy an existing repo's, adjust key + sources).
  3. Add .gitea/workflows/sonarqube.yml (copy verbatim — it's language-agnostic).
  4. Set the SONAR_TOKEN secret and SONAR_HOST_URL variable in the repo's Gitea Actions settings.