Configure SonarQube quality gates and custom rules for automated code quality enforcement

Intermediate 45 min Apr 20, 2026 1,284 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Set up SonarQube quality gates with custom conditions, create language-specific rules, and integrate automated quality enforcement into CI/CD pipelines for continuous code quality monitoring.

Prerequisites

  • SonarQube server running
  • Administrative access to SonarQube
  • CI/CD pipeline access
  • Basic understanding of code quality metrics

What this solves

SonarQube quality gates enforce code quality standards by blocking deployments when code doesn't meet defined criteria. This tutorial shows you how to configure custom quality gates with specific conditions, create custom rules for different programming languages, and integrate quality enforcement into CI/CD pipelines. You'll also set up monitoring and alerting for code quality metrics.

Step-by-step configuration

Install SonarQube scanner CLI tools

Install the SonarQube scanner on your development and CI/CD machines to analyze code and send results to your SonarQube server.

wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-5.0.1.3006-linux.zip
sudo unzip sonar-scanner-cli-5.0.1.3006-linux.zip -d /opt/
sudo mv /opt/sonar-scanner-5.0.1.3006-linux /opt/sonar-scanner
sudo ln -s /opt/sonar-scanner/bin/sonar-scanner /usr/local/bin/sonar-scanner
wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-5.0.1.3006-linux.zip
sudo unzip sonar-scanner-cli-5.0.1.3006-linux.zip -d /opt/
sudo mv /opt/sonar-scanner-5.0.1.3006-linux /opt/sonar-scanner
sudo ln -s /opt/sonar-scanner/bin/sonar-scanner /usr/local/bin/sonar-scanner

Configure SonarQube scanner properties

Set up the scanner configuration to connect to your SonarQube server and define project settings.

# SonarQube server configuration
sonar.host.url=https://sonarqube.example.com
sonar.login=your-auth-token

# Global analysis properties
sonar.sourceEncoding=UTF-8
sonar.exclusions=**/*test*/**,**/*.spec.js,**/node_modules/**,**/vendor/**
sonar.coverage.exclusions=**/*test*/**,**/*.spec.js

# Language-specific settings
sonar.java.binaries=target/classes
sonar.javascript.lcov.reportPaths=coverage/lcov.info
sonar.python.coverage.reportPaths=coverage.xml

Create custom quality gate

Access your SonarQube web interface and create a custom quality gate with specific conditions for your projects.

Note: Log into SonarQube as an administrator to access quality gate configuration.

Navigate to Quality Gates > Create and configure the following conditions:

# Coverage conditions
Coverage on New Code: is less than 80%
Line Coverage on New Code: is less than 80%
Branch Coverage on New Code: is less than 70%

# Reliability conditions
Reliability Rating on New Code: is worse than A
Bugs on New Code: is greater than 0

# Security conditions
Security Rating on New Code: is worse than A
Security Hotspots Reviewed on New Code: is less than 100%
Vulnerabilities on New Code: is greater than 0

# Maintainability conditions
Maintainability Rating on New Code: is worse than A
Code Smells on New Code: is greater than 5
Technical Debt on New Code: is greater than 1h

# Duplications
Duplicated Lines (%) on New Code: is greater than 3%

Configure custom rules for Java

Create custom rules specific to Java development standards in your organization.

# Create custom rule profile
# Navigate to Rules > Create Custom Rule
# Select Java language and template

# Example: Method complexity rule
Rule Key: custom-java-method-complexity
Name: Method Cyclomatic Complexity
Description: Methods should not be too complex
Type: Code Smell
Severity: Major
Template: Avoid too complex method
Parameters:
  - Complexity Threshold: 10
  - Message: Method complexity is {0}, max allowed is {1}

# Example: Class naming convention
Rule Key: custom-java-class-naming
Name: Class Naming Convention
Description: Classes must follow naming standards
Type: Code Smell
Severity: Minor
Template: Track usage of a class
Parameters:
  - Pattern: ^[A-Z][a-zA-Z0-9]*$
  - Message: Class name should be PascalCase

Configure custom rules for JavaScript/TypeScript

Set up JavaScript and TypeScript specific rules for modern development practices.

# ESLint integration rules
# Navigate to Rules > JavaScript/TypeScript

# Console usage rule
Rule Key: custom-js-no-console
Name: No Console Statements
Description: Console statements should not be used in production
Type: Code Smell
Severity: Minor
ESLint Rule: no-console

# Function complexity rule
Rule Key: custom-js-function-complexity
Name: Function Complexity Limit
Description: Functions should not exceed complexity threshold
Type: Code Smell
Severity: Major
ESLint Rule: complexity
Parameters:
  - max: 8

# Unused variables rule
Rule Key: custom-js-no-unused-vars
Name: No Unused Variables
Description: Variables should be used once declared
Type: Bug
Severity: Major
ESLint Rule: no-unused-vars
Parameters:
  - vars: all
  - args: after-used

Configure custom rules for Python

Create Python-specific rules for code quality and security best practices.

# Python custom rules using Pylint integration
# Navigate to Rules > Python

# Function length rule
Rule Key: custom-python-function-length
Name: Function Length Limit
Description: Functions should not exceed line limit
Type: Code Smell
Severity: Major
Pylint Rule: too-many-lines
Parameters:
  - max-lines: 50

# Import organization rule
Rule Key: custom-python-import-order
Name: Import Order Standard
Description: Imports should follow PEP8 conventions
Type: Code Smell
Severity: Minor
Pylint Rule: wrong-import-order

# Security rule for hardcoded passwords
Rule Key: custom-python-hardcoded-password
Name: No Hardcoded Passwords
Description: Passwords should not be hardcoded
Type: Vulnerability
Severity: Blocker
Bandit Rule: B105

Create quality profile with custom rules

Combine built-in and custom rules into a quality profile that applies to your projects.

# Create new quality profile
# Navigate to Quality Profiles > Create

Profile Name: Enterprise Standards
Language: Java
Parent Profile: Sonar way

# Activate custom rules
Activated Rules:
  - All Sonar way rules (inherited)
  - custom-java-method-complexity (Major)
  - custom-java-class-naming (Minor)
  - Unused private method (Major)
  - Magic numbers should not be used (Minor)
  - Methods should not have too many parameters (Major)

# Severity adjustments
Rule Modifications:
  - Cognitive Complexity: Blocker (was Major)
  - Public classes should have package info: Info (was Minor)
  - Missing JavaDoc: Minor (was Major)

Configure project-specific analysis settings

Set up project configuration file for automated analysis with your custom rules and quality gate.

# Project identification
sonar.projectKey=my-application
sonar.projectName=My Application
sonar.projectVersion=1.0

# Source configuration
sonar.sources=src/main
sonar.tests=src/test
sonar.java.source=17
sonar.java.target=17

# Quality profile assignment
sonar.profile=Enterprise Standards

# Quality gate assignment
sonar.qualitygate=Enterprise Quality Gate

# Coverage settings
sonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml
sonar.junit.reportPaths=target/surefire-reports

# Analysis parameters
sonar.analysis.mode=publish
sonar.scm.provider=git
sonar.links.homepage=https://github.com/company/my-application
sonar.links.ci=https://jenkins.company.com/job/my-application

Set up GitLab CI integration

Configure GitLab CI pipeline to run SonarQube analysis and enforce quality gate status.

stages:
  - test
  - quality-check
  - deploy

variables:
  SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"
  GIT_DEPTH: "0"

sonarqube-check:
  stage: quality-check
  image: sonarsource/sonar-scanner-cli:latest
  cache:
    key: "${CI_JOB_NAME}"
    paths:
      - .sonar/cache
  script:
    - sonar-scanner
      -Dsonar.projectKey=${CI_PROJECT_NAME}
      -Dsonar.sources=.
      -Dsonar.host.url=${SONAR_HOST_URL}
      -Dsonar.login=${SONAR_TOKEN}
      -Dsonar.gitlab.project_id=${CI_PROJECT_ID}
      -Dsonar.gitlab.commit_sha=${CI_COMMIT_SHA}
      -Dsonar.gitlab.ref_name=${CI_COMMIT_REF_NAME}
  only:
    - merge_requests
    - main
    - develop

quality-gate-check:
  stage: quality-check
  image: curlimages/curl:latest
  script:
    - |
      # Wait for quality gate result
      sleep 30
      TASK_ID=$(curl -s -u ${SONAR_TOKEN}: "${SONAR_HOST_URL}/api/ce/component?component=${CI_PROJECT_NAME}" | jq -r '.queue[0].id // .current.id')
      
      # Check task status
      while true; do
        STATUS=$(curl -s -u ${SONAR_TOKEN}: "${SONAR_HOST_URL}/api/ce/task?id=${TASK_ID}" | jq -r '.task.status')
        if [ "$STATUS" = "SUCCESS" ]; then
          break
        elif [ "$STATUS" = "FAILED" ]; then
          echo "SonarQube analysis failed"
          exit 1
        fi
        sleep 10
      done
      
      # Check quality gate status
      QG_STATUS=$(curl -s -u ${SONAR_TOKEN}: "${SONAR_HOST_URL}/api/qualitygates/project_status?projectKey=${CI_PROJECT_NAME}" | jq -r '.projectStatus.status')
      if [ "$QG_STATUS" != "OK" ]; then
        echo "Quality gate failed: $QG_STATUS"
        exit 1
      fi
      echo "Quality gate passed"
  dependencies:
    - sonarqube-check
  only:
    - merge_requests
    - main
    - develop

Configure Jenkins integration

Set up Jenkins pipeline for SonarQube analysis with quality gate enforcement.

pipeline {
    agent any
    
    tools {
        maven 'Maven-3.9'
        jdk 'JDK-17'
    }
    
    environment {
        SONAR_TOKEN = credentials('sonar-token')
        SONAR_HOST_URL = 'https://sonarqube.example.com'
    }
    
    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }
        
        stage('Build and Test') {
            steps {
                sh 'mvn clean compile test'
            }
            post {
                always {
                    junit 'target/surefire-reports/*.xml'
                    publishCoverage adapters: [jacocoAdapter('target/site/jacoco/jacoco.xml')]
                }
            }
        }
        
        stage('SonarQube Analysis') {
            steps {
                withSonarQubeEnv('SonarQube') {
                    sh '''
                        mvn sonar:sonar \
                          -Dsonar.projectKey=${JOB_NAME} \
                          -Dsonar.host.url=${SONAR_HOST_URL} \
                          -Dsonar.login=${SONAR_TOKEN} \
                          -Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml
                    '''
                }
            }
        }
        
        stage('Quality Gate') {
            steps {
                timeout(time: 5, unit: 'MINUTES') {
                    waitForQualityGate abortPipeline: true
                }
            }
        }
        
        stage('Deploy') {
            when {
                anyOf {
                    branch 'main'
                    branch 'develop'
                }
            }
            steps {
                echo 'Deploying application...'
                // Add deployment steps here
            }
        }
    }
    
    post {
        failure {
            emailext (
                subject: "Quality Gate Failed: ${env.JOB_NAME} - ${env.BUILD_NUMBER}",
                body: "Quality gate failed for ${env.BUILD_URL}",
                to: "${env.CHANGE_AUTHOR_EMAIL}"
            )
        }
    }
}

Set up webhook notifications

Configure SonarQube webhooks to send quality gate results to external systems like Slack or Microsoft Teams.

# Navigate to Administration > Configuration > Webhooks
# Create webhook for Slack integration

Name: Slack Quality Gate Notifications
URL: https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK
Secret: your-webhook-secret

# Webhook payload template (JSON)
{
  "text": "Quality Gate Status: {{status}}",
  "attachments": [
    {
      "color": "{{#eq status 'OK'}}good{{else}}danger{{/eq}}",
      "fields": [
        {
          "title": "Project",
          "value": "{{project.name}}",
          "short": true
        },
        {
          "title": "Branch",
          "value": "{{branch.name}}",
          "short": true
        },
        {
          "title": "Quality Gate",
          "value": "{{qualityGate.name}}",
          "short": true
        },
        {
          "title": "Analysis",
          "value": "<{{serverUrl}}/dashboard?id={{project.key}}|View Details>",
          "short": true
        }
      ]
    }
  ]
}

Configure quality gate metrics monitoring

Set up monitoring dashboards and alerts for code quality metrics across projects.

# Install SonarQube Prometheus exporter
wget https://github.com/dmeiners88/sonarqube-prometheus-exporter/releases/download/v1.3.0/sonar-exporter-1.3.0.jar

# Create systemd service
sudo tee /etc/systemd/system/sonar-exporter.service << EOF
[Unit]
Description=SonarQube Prometheus Exporter
After=network.target

[Service]
Type=simple
User=sonar-exporter
Group=sonar-exporter
ExecStart=/usr/bin/java -jar /opt/sonar-exporter/sonar-exporter-1.3.0.jar \
  --sonar.host.url=https://sonarqube.example.com \
  --sonar.login=your-monitoring-token \
  --web.listen-address=:9765
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

# Create user and directories
sudo useradd -r -s /bin/false sonar-exporter
sudo mkdir -p /opt/sonar-exporter
sudo mv sonar-exporter-1.3.0.jar /opt/sonar-exporter/
sudo chown -R sonar-exporter:sonar-exporter /opt/sonar-exporter

# Start service
sudo systemctl enable --now sonar-exporter

Create Grafana dashboard for code quality

Build comprehensive dashboards to visualize code quality trends and quality gate status across projects.

{
  "dashboard": {
    "id": null,
    "title": "SonarQube Code Quality Dashboard",
    "tags": ["sonarqube", "quality"],
    "timezone": "browser",
    "panels": [
      {
        "title": "Quality Gate Status",
        "type": "stat",
        "targets": [
          {
            "expr": "sonar_quality_gate_status",
            "legendFormat": "{{project_name}}"
          }
        ],
        "fieldConfig": {
          "defaults": {
            "mappings": [
              {"options": {"0": {"text": "ERROR", "color": "red"}}},
              {"options": {"1": {"text": "OK", "color": "green"}}}
            ]
          }
        }
      },
      {
        "title": "Code Coverage Trend",
        "type": "graph",
        "targets": [
          {
            "expr": "sonar_coverage_line_coverage",
            "legendFormat": "{{project_name}}"
          }
        ]
      },
      {
        "title": "Technical Debt",
        "type": "graph",
        "targets": [
          {
            "expr": "sonar_technical_debt_minutes",
            "legendFormat": "{{project_name}}"
          }
        ]
      },
      {
        "title": "Security Vulnerabilities",
        "type": "table",
        "targets": [
          {
            "expr": "sonar_vulnerabilities{severity=~\"BLOCKER|CRITICAL|MAJOR\"}",
            "format": "table",
            "instant": true
          }
        ]
      }
    ]
  }
}

Verify your setup

# Test SonarQube scanner
sonar-scanner --version

# Run analysis on sample project
cd /path/to/your/project
sonar-scanner

# Check quality gate API
curl -u your-token: "https://sonarqube.example.com/api/qualitygates/project_status?projectKey=your-project"

# Verify webhook delivery
curl -X POST https://sonarqube.example.com/api/webhooks/deliveries \
  -u your-token: \
  -H "Content-Type: application/json"

# Test Prometheus exporter
curl http://localhost:9765/metrics | grep sonar

Common issues

SymptomCauseFix
Quality gate always passesConditions not properly configuredCheck condition thresholds in Quality Gates > Your Gate > Conditions
Custom rules not appliedQuality profile not assigned to projectGo to Project Settings > Quality Profiles and assign custom profile
Analysis fails with permission errorScanner token lacks analysis permissionsGenerate new token with Execute Analysis permission in SonarQube
Coverage reports not foundIncorrect coverage file pathsVerify coverage report paths match actual file locations
Webhook not triggeredWebhook URL unreachable or invalidTest webhook URL manually and check SonarQube logs
CI pipeline hangs on quality gateQuality gate check timeoutIncrease timeout or check SonarQube background task queue

Next steps

Automated install script

Run this to automate the entire setup

不想自己管理这些吗?

我们为依赖稳定运行时间的企业管理基础设施。全托管服务,配备一位熟悉您系统架构的固定联系人。

您将拥有一位了解您整体架构的固定联系人

在鹿特丹的办公桌前 13:01 · 一条消息即可联系我们,无需填写工单表单