sonarqube-rules
Configures and runs SonarQube / SonarCloud - multi-language SAST + Quality Gate platform with built-in Sonar Way rule profiles + custom rule plugins; integrates `sonar-scanner` with `sonar-project.properties` config; supports Quality Gate definitions including new-code-period blocking, branch + PR analysis, and per-issue suppression via `// NOSONAR` comment or `@SuppressWarnings("squid:RULE_ID")` annotation. Use when the user runs SonarQube Community / Developer / Enterprise edition or SonarCloud, or needs a multi-language SAST + code-quality platform with persistent issue tracking.
sonarqube-rules
Overview
Per github.com/SonarSource/sonarqube:
"SonarQube provides the capability to not only show the health of an application but also to highlight issues newly introduced."
The platform's distinguishing features vs Semgrep / CodeQL:
When to use
For new projects without a SonarQube investment, evaluate semgrep-rules (lower friction; no server) first.
Step 1 - Install (server side)
Per docs.sonarsource.com/sonarqube-server:
Docker (most common for evaluation):
docker run -d --name sonarqube \
-p 9000:9000 \
sonarqube:lts-communityFor production, consult sq-docs for Postgres + JVM sizing + reverse-proxy configuration. Default admin: admin / admin (change immediately).
Step 2 - sonar-scanner CLI
Download from docs.sonarsource.com/sonarqube-server → "Analysis scanners". Place on PATH.
sonar-scanner \
-Dsonar.projectKey=my-project \
-Dsonar.sources=. \
-Dsonar.host.url=http://localhost:9000 \
-Dsonar.token=$SONAR_TOKENFor Maven / Gradle / .NET, use the language-native scanner plugin (mvn sonar:sonar / ./gradlew sonar / dotnet sonarscanner).
Step 3 - sonar-project.properties config
Project-root file replaces -D flags:
# sonar-project.properties
sonar.projectKey=my-project
sonar.projectName=My Project
sonar.sources=src
sonar.tests=tests
sonar.exclusions=**/*.spec.ts,**/generated/**
sonar.sourceEncoding=UTF-8
# Coverage from external tool (Jest, JaCoCo, etc.)
sonar.javascript.lcov.reportPaths=coverage/lcov.info
# New-code-period (analysis scope)
sonar.newCode.referenceBranch=main
# Quality Gate (referenced by ID; created via UI/API)
sonar.qualitygate.wait=truesonar.qualitygate.wait=true makes the scanner block until the gate decision is computed - critical for CI gating.
Step 4 - Quality Gate concept
The default "Sonar Way" gate enforces (consult your SonarQube UI at Quality Gates → Sonar Way for current conditions):
Custom gates can be defined via UI or REST API (/api/qualitygates/create).
Step 5 - Branch + PR analysis
For PR analysis (Developer edition+):
sonar-scanner \
-Dsonar.pullrequest.key=$PR_NUMBER \
-Dsonar.pullrequest.branch=$PR_BRANCH \
-Dsonar.pullrequest.base=mainPR results post as comments to GitHub / GitLab / Bitbucket per the integration setup in SonarQube admin.
Step 6 - False-positive triage (MANDATORY)
Three suppression layers in priority order:
| Mechanism | Example | When to use |
|---|---|---|
Per-line NOSONAR | int x = 0; // NOSONAR justification text | Single-line exception with inline reason |
| Annotation | @SuppressWarnings("squid:S106") | Java/Kotlin per-block exception |
| Server-side mark-as-FP | UI: Issues → Resolve as False Positive | Persistent across scans; auditable |
| Server-side mark-as-Won't Fix | UI: Issues → Resolve as Won't Fix | Acknowledged risk; not a defect |
Justification template (mandatory in code):
// NOSONAR squid:S106 - Reason: required for CLI tool stdout output
// Reviewer: alice@example.com (2026-05-15)
// Expires: 2026-12-15
System.out.println(message);Server-side resolution requires a comment per SonarQube workflow config - make it mandatory in admin settings (Administration → Configuration → Issues → Comment required to set status).
Cadence: Issues → False Positive filter periodically; review for expiration. Server-side resolutions are persistent and auditable - the audit trail is the value over Semgrep's per-comment approach.
Step 7 - CI integration
jobs:
sonarqube:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with: { fetch-depth: 0 } # full history needed for new-code-period
- uses: SonarSource/sonarqube-scan-action@v5
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
- uses: SonarSource/sonarqube-quality-gate-action@v1
timeout-minutes: 5
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}fetch-depth: 0 is critical - without full git history, new-code-period detection is broken.
Step 8 - REST API integration
For automation / dashboards:
| Endpoint | Use |
|---|---|
GET /api/issues/search?projectKeys=... | Issue list with filters |
GET /api/qualitygates/project_status | Current gate verdict |
POST /api/issues/do_transition | Mark FP / Won't Fix |
GET /api/measures/component_tree | Per-file metrics |
API token via User → My Account → Security → Generate Tokens.
Anti-patterns
| Anti-pattern | Why it fails | Fix |
|---|---|---|
fetch-depth: 1 in CI | New-code-period broken; gates produce wrong decisions | Always fetch-depth: 0 (Step 7) |
Skip sonar.qualitygate.wait | CI exits before gate evaluates; missed regressions | sonar.qualitygate.wait=true (Step 3) |
| NOSONAR without justification | Server-side audit trail empty | Required template (Step 6) |
| Custom Quality Gate without team buy-in | Gate fails on PRs no one understands | Document gate definition; reference in PR template |
| Mass-resolve as FP without review | Backdoor for skipping security findings | Require comment + reviewer attribution (Step 6) |