diff --git a/ci/SONARQUBE.md b/ci/SONARQUBE.md new file mode 100644 index 0000000..7d73256 --- /dev/null +++ b/ci/SONARQUBE.md @@ -0,0 +1,59 @@ +# 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 | + +## 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.