Scope SonarQube Quality Gates to New Code to Keep Pipelines Actionable
Enforcing SonarQube Quality Gates on Overall Code blocks builds on legacy debt. Configure conditions against New Code metrics and use sonar.qualitygate.wait=true so CI fails only on recent changes.
20 Jul 2025, 11:23 UTC

The Problem: Legacy Debt Blocks Every Build
When a SonarQube Quality Gate enforces conditions on Overall Code, every historical issue counts against the current pipeline. A team inheriting a legacy codebase sees a red gate on the first commit, even if that commit is clean. Over time, developers learn to ignore the failure or bypass the check entirely. The practical fix is to scope the gate to New Code—the changes introduced since a defined baseline—so the pipeline only fails on issues the current team can act on.
How New Code Scoping Works
SonarQube defines a New Code period for each project. This period acts as a moving baseline: it can be the previous version, a specific number of days, or a reference branch. Quality Gate conditions can then target metrics such as Coverage on New Code, Duplicated Lines on New Code, or the maintainability, reliability, and security ratings applied only to new code. Overall Code metrics remain visible in the user interface for reporting, but they are not enforced when the gate checks only New Code.
Quality Gate Conditions
A Quality Gate is a set of pass/fail conditions. To scope it to New Code, create conditions that explicitly reference New Code metrics rather than their Overall Code equivalents. The following table shows a typical configuration:
| Metric | Operator | Value | Scope |
|---|---|---|---|
| Coverage | is less than | 80% | New Code |
| Duplicated Lines | is greater than | 3% | New Code |
| Maintainability Rating | is worse than | A | New Code |
Assign this gate to the target project. Then, in Project Settings, set the New Code definition to a short, predictable window—for example, 30 days or the previous version. The exact labels and available options vary across SonarQube versions, so verify the setting names in your deployment.
Worked Configuration: Scanner Properties
The Quality Gate is evaluated during analysis, but the CI job only fails if the scanner waits for the result. Run the scanner in your pipeline with the standard connection properties and the wait flag:
sonar-scanner \
-Dsonar.projectKey=<PROJECT_KEY> \
-Dsonar.sources=<SOURCE_DIRECTORY> \
-Dsonar.host.url=<SONAR_HOST_URL> \
-Dsonar.token=<SONAR_TOKEN> \
-Dsonar.qualitygate.wait=true
Run this command from the repository root or the directory containing your build files. The token requires Execute Analysis permission on the project. Without sonar.qualitygate.wait=true, the scanner uploads results and exits successfully even when the gate is red; the pipeline reports the status but does not break the build.
Expected Checks
- The scanner output should indicate that it is waiting for the Quality Gate result.
- The CI step should exit with a non-zero code when the gate fails.
- The SonarQube UI should show the gate status as passed or failed based on the New Code conditions.
Limits and Version-Specific Behavior
New Code is a project-level setting. In a multi-project portfolio, different teams can drift to inconsistent baselines—one project using 30 days, another using the previous version—which makes cross-project comparisons unreliable. Standardize the definition where possible.
Pull Request analysis is separate from the standard New Code gate. It requires additional parameters such as sonar.pullrequest.key, sonar.pullrequest.branch, and sonar.pullrequest.base, plus a supported ALM (Application Lifecycle Management) integration—for example, GitHub, GitLab, or Azure DevOps. If the ALM binding or environment variables are missing, PR analysis may silently disable rather than fail loudly.
The sonar.qualitygate.wait parameter requires a scanner version that supports it. Behavior can also differ in containerized pipelines or PR contexts. Verify the exact property names and UI labels against your SonarQube version before rolling the change out broadly.
Common Mistakes
Gating on Overall Code
Setting conditions against Overall Code metrics re-introduces the legacy debt problem. A single historical blocker can fail every subsequent build, regardless of the quality of new commits.
Forgetting the Wait Flag
Uploading analysis results without sonar.qualitygate.wait=true means the pipeline never sees the gate verdict. The build stays green while the SonarQube dashboard shows a failure.
Overly Strict Thresholds
A gate that requires 100% coverage or zero duplication on New Code will be bypassed. Set thresholds that are ambitious but achievable for the current team.
Changing the New Code Period Mid-Sprint
Shortening or lengthening the New Code window silently changes what is measured. A developer who passed the gate on Monday may fail on Wednesday because the baseline moved, not because the code changed.
Practical Verification
After configuring the gate, verify it behaves as intended before relying on it in production pipelines:
- Open the project in the SonarQube UI and confirm the Quality Gate status reflects the New Code conditions you configured.
- On a test branch, add a small amount of uncovered code or duplication that exceeds the threshold. Run the scanner with
sonar.qualitygate.wait=trueand confirm the CI job fails. - Compare the New Code and Overall Code columns on the Measures page to ensure the gate is evaluating the intended scope.
Once verified, the gate becomes a fast feedback signal: it fails only when recent changes introduce new problems, and it leaves historical debt visible for separate remediation planning.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.