SonarQube Integration with Azure DevOps

Azure DevOps (ADO) is Microsoft's cloud-based DevOps platform that includes pipelines, repositories, boards, and artifact management. Integrating SonarQube with Azure DevOps pipelines gives every build automatic code quality analysis. This topic covers the setup for both YAML pipelines and the classic pipeline editor.

What the Integration Provides

AZURE DEVOPS PIPELINE
  |
  +-- SonarQube extension installed
  |
  +-- Pipeline stages:
       1. Prepare Analysis (configure the scan)
       2. Build and Test your code
       3. Run Code Analysis (execute the scan)
       4. Publish Quality Gate Result (check gate)
               |
               +-- PASSED --> Pipeline continues
               +-- FAILED --> Pipeline breaks, PR blocked

Step 1: Install the SonarQube Extension

The SonarQube extension adds pipeline tasks that simplify the integration. Install it from the Azure DevOps Marketplace:

  1. Go to your Azure DevOps organization
  2. Click the shopping bag icon (Marketplace) in the top right
  3. Search for SonarQube
  4. Click the official SonarQube extension by SonarSource
  5. Click Get it free and install it in your organization

Step 2: Create a Service Connection

A service connection stores the SonarQube server URL and token so pipelines can authenticate without hardcoding credentials.

  1. Go to Project Settings > Service connections
  2. Click New service connection
  3. Select SonarQube from the list
  4. Enter the server URL and authentication token
  5. Name it (e.g., SonarQube-Production)
  6. Save
SERVICE CONNECTION
+----------------------------------------------+
| Type: SonarQube                              |
| Name: SonarQube-Production                   |
| Server URL: http://sonarqube.company.com:9000|
| Token: [stored securely]                     |
+----------------------------------------------+

YAML Pipeline Configuration

Add the following to your azure-pipelines.yml file in the repository root:

trigger:
  branches:
    include:
      - main
      - develop

pool:
  vmImage: 'ubuntu-latest'

variables:
  MAVEN_CACHE_FOLDER: $(Pipeline.Workspace)/.m2/repository

steps:

- task: SonarQubePrepare@6
  displayName: 'Prepare SonarQube Analysis'
  inputs:
    SonarQube: 'SonarQube-Production'
    scannerMode: 'Other'
    extraProperties: |
      sonar.projectKey=com.acme:customer-portal
      sonar.projectName=Customer Portal
      sonar.sources=src/main
      sonar.tests=src/test
      sonar.coverage.jacoco.xmlReportPaths=$(System.DefaultWorkingDirectory)/target/site/jacoco/jacoco.xml

- task: Maven@4
  displayName: 'Build and Test'
  inputs:
    mavenPomFile: 'pom.xml'
    goals: 'clean verify'
    publishJUnitResults: true
    testResultsFiles: '**/surefire-reports/TEST-*.xml'

- task: SonarQubeAnalyze@6
  displayName: 'Run SonarQube Analysis'
  inputs:
    jdkversion: 'JAVA_HOME_17_X64'

- task: SonarQubePublish@6
  displayName: 'Publish Quality Gate Result'
  inputs:
    pollingTimeoutSec: '300'

The Four SonarQube Tasks Explained

SonarQubePrepare    Sets up configuration before build
                    Tells the scanner what project to scan
                    Must run BEFORE the build step

SonarQubeAnalyze    Runs the actual scan after the build
                    Collects source, test, coverage data
                    Sends data to the SonarQube server

SonarQubePublish    Waits for analysis results on the server
                    Breaks the pipeline if Quality Gate fails
                    Shows the gate status in the build summary

Scanner Mode Options

The scannerMode property in the Prepare task has three values:

scannerMode: 'MSBuild'
  Use for: .NET projects
  How: Wraps MSBuild commands with begin/end markers

scannerMode: 'Maven' or 'Gradle'
  Use for: Java Maven or Gradle projects
  How: Works through the build tool plugin

scannerMode: 'Other'
  Use for: All other projects (CLI scanner)
  How: Runs the standalone SonarScanner CLI

Pipeline for .NET Projects

steps:

- task: SonarQubePrepare@6
  inputs:
    SonarQube: 'SonarQube-Production'
    scannerMode: 'MSBuild'
    projectKey: 'com.acme:dotnet-api'
    projectName: 'DotNet API'

- task: DotNetCoreCLI@2
  displayName: 'Build'
  inputs:
    command: 'build'
    projects: '**/*.csproj'

- task: DotNetCoreCLI@2
  displayName: 'Test'
  inputs:
    command: 'test'
    projects: '**/*Tests.csproj'
    arguments: '--collect:"XPlat Code Coverage"'

- task: SonarQubeAnalyze@6

- task: SonarQubePublish@6
  inputs:
    pollingTimeoutSec: '300'

Pull Request Analysis in Azure DevOps

SonarQube can decorate Azure DevOps pull requests with inline comments showing issues found in the changed code. Configure this in SonarQube:

  1. Go to Administration > Configuration > Azure DevOps
  2. Enter your Azure DevOps organization name and a Personal Access Token
  3. The token needs Code: Read & Write permission

When a PR scan runs, SonarQube posts the Quality Gate result as a comment on the PR and marks each issue inline at the specific line of code that caused it.

AZURE DEVOPS PULL REQUEST
+--------------------------------------------------+
| PR #147: Feature - Add payment gateway           |
| Branch: feature/payment-gateway → main           |
|                                                  |
| Policies:  [SonarQube: Quality Gate Failed] ✗    |
|                                                  |
| SonarQube Bot commented:                         |
| "Quality Gate: Failed                            |
|  - 1 new vulnerability found                     |
|  - Coverage dropped to 61% (required: 80%)"      |
+--------------------------------------------------+

Branch Policy Enforcement

In Azure DevOps, you can set a Branch Policy that requires the SonarQube build to pass before a PR can be completed. This prevents developers from merging code that fails the Quality Gate, even if the repository owner tries to override it.

  1. Go to Repos > Branches
  2. Click the three-dot menu next to main
  3. Select Branch policies
  4. Under Build Validation, add your SonarQube pipeline
  5. Set to Required

Leave a Comment

Your email address will not be published. Required fields are marked *