Linters catch style. Reviewers catch design. In between sits a category of problem nobody reliably catches: a null dereference on an error path, a resource never closed, coverage quietly sliding down for six months, the same forty lines pasted into four services.

SonarQube analyses the codebase for those and turns the result into a quality gate — a pass or fail the pipeline can act on.

Which edition

The free self-hosted edition is Community Build. It analyses the main branch and reports on the project; branch analysis and pull-request decoration are paid features, as is the deeper security analysis. SonarQube Cloud (formerly SonarCloud) is the hosted version and is free for public repositories — which, for open source, is the best deal here.

  docker run -d --name sonarqube -p 9000:9000 sonarqube:community
  

Log in at localhost:9000 (admin/admin), create a project, and generate a token.

Analyse a project

  # JS/TS, Python, Go, PHP… anything without a special build integration
npx sonarqube-scanner \
  -Dsonar.projectKey=my-app \
  -Dsonar.host.url=http://localhost:9000 \
  -Dsonar.token=$SONAR_TOKEN
  
  # sonar-project.properties
sonar.projectKey=my-app
sonar.sources=src
sonar.tests=tests
sonar.javascript.lcov.reportPaths=coverage/lcov.info
sonar.exclusions=**/generated/**,**/*.min.js
  

JVM projects use the Maven or Gradle plugin instead; C/C++ needs the build wrapper. Feed it your coverage report — that line above is what turns coverage from a number in a CI log into something the gate can hold you to.

Clean as You Code, which is the part that works

The instinct with a legacy codebase is to fix everything, and the result is a backlog of eleven thousand issues that everyone learns to ignore.

SonarQube’s default gate looks only at new code — what changed since the last version: no new bugs, no new vulnerabilities, coverage on new lines above 80%, duplication under 3%. The old debt stays visible but doesn’t block anyone. Every change makes the codebase slightly better, and nobody has to stop for a cleanup quarter.

Set that gate, and resist the urge to raise the bar on old code until the new-code habit sticks.

In CI

  - uses: SonarSource/sonarqube-scan-action@v6
  env:
    SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
    SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}

- uses: SonarSource/sonarqube-quality-gate-action@v1   # fail the build on a red gate
  timeout-minutes: 5
  env:
    SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
  

Run it after your tests, so the coverage report exists by the time the scanner looks for it.

Where it stops

  • It is not a replacement for review. It has no idea whether the feature is right.
  • False positives happen. Mark them as such in the UI with a reason — never by loosening the rule for everyone.
  • A gate that always fails gets bypassed. If the team is routinely overriding it, the thresholds are wrong; fix them rather than pretending.

Lighter alternatives worth knowing: pre-commit hooks with language-native linters cover a lot for zero infrastructure, and Semgrep is a good middle ground for security-flavoured rules.

Next

Where the artifact you just built goes → Nexus Repository

Last updated 25 Aug 2026, 00:00 UTC. history