Where the scan stage goes
flowchart LR
C["Checkout"] --> B["Build + unit tests<br/>(produce coverage)"]
B --> S["SonarQube scan"]
S --> Q{"Quality Gate"}
Q -- "Passed" --> I["Build image"] --> D["Deploy"]
Q -- "Failed" --> X["Stop the pipeline"]
Put the scan after tests (so the coverage report exists) and before the image build and deploy to block early. Run it on every pull request so developers see results in the PR.
Configuring Jenkins
- Manage Jenkins → Plugins: install SonarQube Scanner for Jenkins.
- Tools: add a SonarQube Scanner installation (installed automatically).
- System: declare the server, for example named
sonar-server, URLhttp://sonarqube.example.com:9000, and pick a Secret text credential holding the token. - On SonarQube: Administration → Configuration → Webhooks, add a webhook to
https://jenkins.example.com/sonarqube-webhook/so the server reports the Quality Gate result to Jenkins.
pipeline {
agent any
stages {
stage('Test') { steps { sh 'npm ci && npm test -- --coverage' } }
stage('SonarQube') {
steps {
withSonarQubeEnv('sonar-server') {
sh 'sonar-scanner -Dsonar.projectKey=example-org_myapp'
}
}
}
stage('Quality Gate') {
steps {
timeout(time: 5, unit: 'MINUTES') {
waitForQualityGate abortPipeline: true
}
}
}
}
}
withSonarQubeEnv injects the URL and token into the environment of the steps inside it. waitForQualityGate waits for the webhook; abortPipeline: true fails the build when the gate fails, and timeout prevents hanging forever if the webhook never arrives.
Other platforms
| Platform | Integration |
|---|---|
| GitHub Actions | The SonarSource/sonarqube-scan-action action with SONAR_TOKEN and SONAR_HOST_URL in secrets |
| GitLab CI | A job using the sonarsource/sonar-scanner-cli image, with optional merge request decoration |
| Azure DevOps | The SonarQube extension: Prepare, Analyze, Publish tasks |
| Maven | mvn verify sonar:sonar |
Developer edition and above offer pull request decoration: new issues appear as comments on the PR.
Traps
- Writing the token into the Jenkinsfile instead of credentials.
- Scanning after deploy, so broken code reaches an environment before it is caught.
- Using
waitForQualityGatewithout a webhook: the stage hangs until the timeout. - Leaving out
abortPipeline: true, so the gate fails but the pipeline stays green.