From c54bb54834b30a13eb612e55b916967ccacfbc34 Mon Sep 17 00:00:00 2001 From: wtclaude Date: Mon, 20 Jul 2026 21:43:00 -0500 Subject: [PATCH] ci(sonarqube): add non-blocking SonarQube analysis on push to main Wire the self-hosted SonarQube server into Gitea via a Gitea Actions workflow. Runs on push to `main` (post-merge) and workflow_dispatch, so it feeds the dashboard without gating any PR. Adds sonar-project.properties (project key runic-gateway-website; server/client/bot sources, server tests, node_modules/dist/generated excluded). Requires two one-time Gitea settings: secret SONAR_TOKEN and variable SONAR_HOST_URL. The scan does not wait on the Quality Gate, keeping it fully non-blocking. Co-Authored-By: Claude --- .gitea/workflows/sonarqube.yml | 48 ++++++++++++++++++++++++++++++++++ sonar-project.properties | 20 ++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 .gitea/workflows/sonarqube.yml create mode 100644 sonar-project.properties diff --git a/.gitea/workflows/sonarqube.yml b/.gitea/workflows/sonarqube.yml new file mode 100644 index 0000000..4fa4f85 --- /dev/null +++ b/.gitea/workflows/sonarqube.yml @@ -0,0 +1,48 @@ +# Run SonarQube static analysis against the code that just landed on `main` and +# report the results to the self-hosted SonarQube server for review. This is +# intentionally NON-BLOCKING: it triggers on push to main (i.e. AFTER merge), +# not on pull_request, so it never gates a PR. It complements pr-checks.yml +# (which gates PRs) and build-images.yml (which ships images) — this one only +# feeds the dashboard. +# +# Prerequisites (one-time, in the Gitea UI — Repo → Settings → Actions): +# • Secret SONAR_TOKEN — a SonarQube "Analysis" token generated at +# My Account → Security in SonarQube for the +# runic-gateway-website project (or a global one). +# • Variable SONAR_HOST_URL — the SonarQube base URL on your LAN, e.g. +# http://192.168.0.56:9000 +# (kept as a variable, not committed, so the internal address stays out of git.) +# +# The runner (self-hosted `ubuntu-latest`, same as the other workflows) must be +# able to reach SONAR_HOST_URL on your network. Nothing here waits on the +# SonarQube Quality Gate, so a failing gate does not fail this job — check the +# dashboard when you want to. + +name: SonarQube + +on: + push: + branches: [main] + # Allow re-running the analysis on demand from the Actions tab. + workflow_dispatch: {} + +concurrency: + group: sonarqube-${{ github.ref }} + cancel-in-progress: true + +jobs: + analysis: + runs-on: ubuntu-latest + steps: + - name: Check out (full history for accurate new-code + blame) + uses: actions/checkout@v4 + with: + # SonarQube uses git history to attribute issues to authors and to + # compute "new code". A shallow clone degrades both. + fetch-depth: 0 + + - name: Run SonarQube scan + uses: sonarsource/sonarqube-scan-action@v4 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }} diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000..ed4b092 --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,20 @@ +# SonarQube analysis config for the website repo. +# Consumed by the scanner in .gitea/workflows/sonarqube.yml on push to main. +# The project key must match the one created in SonarQube (dashboard URL +# ?id=runic-gateway-website). + +sonar.projectKey=runic-gateway-website +sonar.projectName=runic gateway website + +# Analysed application code. The three npm workspaces (server / client / bot). +sonar.sources=server/src,client/src,bot/src + +# Test code is analysed separately from sources so coverage/metrics attribute +# correctly. Only the server has a test suite today. +sonar.tests=server/test +sonar.test.inclusions=server/test/**/*.test.js + +# Never analyse dependencies, build output, generated specs, or runtime dirs. +sonar.exclusions=**/node_modules/**,client/dist/**,client/public/**,server/swagger/**,server/logs/**,server/uploads/**,**/*.min.js + +sonar.sourceEncoding=UTF-8 -- 2.49.1