Start Free
10.7 | DevOps platform integration | Azure DevOps integration

Azure DevOps integration

On this page

SonarQube's integration with Azure DevOps allows you to maintain code quality and security in your Azure DevOps repositories. It is compatible with both Azure DevOps Server and Azure DevOps Services.

With this integration, you'll be able to:

  • Import your Azure DevOps repositories: Import your Azure DevOps repositories into SonarQube to easily set up SonarQube projects.
  • Analyze projects with Azure Pipelines - Integrate analysis into your build pipeline. Starting in Developer Edition, the SonarQube Extension running in Azure Pipelines jobs can automatically detect branches or pull requests being built, so you don't need to specifically pass them as parameters to the scanner.
  • Report your quality gate status to your pull requests (starting in Developer Edition): See your quality gate and code metric results right in Azure DevOps so you know if it's safe to merge your changes.

Prerequisites

  • Integration with Azure DevOps Server requires Azure DevOps Server 2022, Azure DevOps Server 2020, and Azure DevOps Server 2019 (including Express editions).
  • You've set a SonarQube Server base URL in Administration > Configuration > General Settings > General.

Branch analysis

Community Edition doesn't support the analysis of multiple branches, so you can only analyze your main branch. Starting in Developer Edition, you can analyze multiple branches and pull requests.

If you're using Community Edition and your codebase is not stored on Azure Repos, your default branch must be named "master" for analysis to work.

Importing your Azure DevOps repositories into SonarQube

Setting up the import of Azure DevOps repositories into SonarQube allows you to easily create SonarQube projects from your Azure DevOps repositories. If you're using Developer Edition or above, this is also the first step in adding pull request decoration.

To set up the import of Azure DevOps repositories:

  1. Set your global DevOps platform settings
  2. Add a personal access token for importing repositories

Setting your global settings

To import your Azure DevOps repositories into SonarQube, you need to first set your global SonarQube settings. Navigate to Administration > Configuration > General Settings > DevOps Platform Integrations, select the Azure DevOps tab, and select the Create configuration button. Specify the following settings:

  • Configuration Name (Enterprise and Data Center Edition only): The name used to identify your Azure DevOps configuration at the project level. Use something succinct and easily recognizable.
  • Azure DevOps collection/organization URL: If you are using Azure DevOps Server, provide your full Azure DevOps collection URL. For example, https://ado.your-company.com/DefaultCollection. If you are using Azure DevOps Services, provide your full Azure DevOps organization URL. For example, https://dev.azure.com/your_organization.
  • Personal Access Token: An Azure DevOps user account is used to decorate Pull Requests. We recommend using a dedicated Azure DevOps account with Administrator permissions. You need a personal access token from this account with the scope authorized for Code > Read & write for the repositories that will be analyzed. Administrators can encrypt this token at Administration > Configuration > Encryption. See the Settings Encryption section of the Security page for more information. This personal access token is used to report your quality gate status to your pull requests. You'll be asked for another personal access token for importing projects in the following section.

Personal access tokens

Personal access tokens (PATs) contain the security credentials for Azure DevOps and identify your SonarQube instance as an accessible organization to define its scope of access.

How PATs work

During a normal analysis using the SonarQube extension for Azure DevOps, Azure sends information to Sonar and the results are displayed in SonarQube. In a pull request analysis, Azure sends information to Sonar. Next, Sonar analyzes the code and then sends the results back to Azure; here, a PAT is needed so that Azure knows to accept the results of your Sonar analysis.

Updating your PAT in SonarQube

After setting up an Azure DevOps PAT in your global settings, return to the same SonarQube page, Administration > Configuration > General Settings > DevOps Platform Integrations > Azure DevOps, and select the Edit button, then Update field value, to change your Azure PAT in SonarQube.

PAT failure points

  • Azure PATs require an expiration date. Check the Microsoft documentation for details when creating your PAT.
  • Azure requires that a user log in every 30 days, or it automatically kills a PAT; this action may cause your related pipeline to fail. Here is an Azure Q&A on this topic.

Users having the Stakeholder access type can have problems finding their repos when trying to Analyze projects; the Basic access type should be used instead. 

Additionally, in your Azure DevOps organization, you will need to ensure that Azure Active Directory Conditional 

Adding a personal access token for importing repositories

After setting your global settings, you can add a project from Azure DevOps by selecting the Create project button in the upper-right corner of the Projects homepage and From Azure DevOps.

Then, you'll be asked to provide a Personal Access Token with Code (Read & Write) scope so SonarQube can access and list your Azure DevOps projects. This token will be stored in SonarQube and can be revoked at any time in Azure DevOps.

After saving your personal access token, you'll see a list of your Azure DevOps projects that can be set up and added to SonarQube. Setting up your projects this way also defines your project settings for pull request decoration.

For information on analyzing your projects with Azure Pipelines, see the Analyzing projects with Azure Pipelines section below.

Analyzing projects with Azure Pipelines

The SonarQube extension running in Azure Pipelines jobs can automatically detect branches or pull requests being built, so you don't need to specifically pass them as parameters to the scanner.

Installing your extension

From the Visual Studio Marketplace, install the SonarQube extension by clicking the Get it free button.

Azure DevOps server - build agents

If you are using Microsoft-hosted build agents then there is nothing else to install. The extension will work with all of the hosted agents (Windows, Linux, and macOS).

If you are self-hosting the build agents, make sure you have at least the minimum SonarQube-supported version of Java installed.

Adding a new SonarQube service endpoint

After installing your extension, you need to declare your SonarQube server as a service endpoint in your Azure DevOps project settings:

  1. In Azure DevOps, go to Project Settings > Service connections.
  2. Select New service connection and then select SonarQube from the service connection list.
  3. Enter your SonarQube Server URL, an authentication token, and a memorable Service connection name. Then, select Save to save your connection.

Configuring branch analysis

After adding your SonarQube service endpoint, you'll need to configure branch analysis. You'll use the following tasks in your build definitions to analyze your projects:

  • Prepare analysis configuration: This task configures the required settings before executing the build. For more details, see the Using the Prepare Analysis Configuration task article below.
  • Run code analysis (Not used in Maven or Gradle projects): This task executes the analysis of source code. You can specify which version of Java to use for analysis. The options are:
    • JAVA_HOME:  The scanner picks up the current value of the JAVA_HOME environment variable on the system, so you are free to choose the value. The specified version must be supported by SonarQube.
    • JAVA_HOME_11_X64: When you run your pipeline on a self-hosted build agent, this variable is normally set, and the scanner picks it up automatically. If no variable is detected, the scanner uses the value of JAVA_HOME.
    • JAVA_HOME_17_X64: When you run your pipeline on a self-hosted build agent, this variable is normally set, and the scanner picks it up automatically. If no variable is detected, the scanner uses the value of JAVA_HOME.
  • Publish quality gate result: This task displays the quality gate status in the build summary letting you know if your code meets quality standards for production. This task may increase your build time as your pipeline has to wait for SonarQube to process the analysis report. It is highly recommended but optional.

Select your build technology below to expand the instructions for configuring branch analysis and to see an example .yml file.

Gradle or Maven

Steps to construct your Azure pipeline for Gradle or Maven

  1. In Azure DevOps, create or edit a Build Pipeline, and add a new Prepare Analysis Configuration task before your build task:
    • Select the SonarQube server endpoint you created in the Adding a new SonarQube Service Endpoint section.
    • Under Choose a way to run the analysis, select Integrate with Maven or Gradle.
    • Expand the Advanced section and replace the Additional Properties with the following snippet:
      • # Additional properties that will be passed to the scanner,
        # Put one key=value per line, example:
        # sonar.exclusions=**/*.bin
        sonar.projectKey=YourProjectKey
  2. Edit or add a new Maven or Gradle task
    • Under Code Analysis, check Run SonarQube or SonarCloud Analysis.
  3. Add a new Publish quality gate Result on your build pipeline summary.
  4. Under the Triggers tab of your pipeline, select Enable continuous integration, and choose all of the branches for which you want SonarQube analysis to run automatically.
  5. Save your pipeline.

.yml example:

trigger:
- master # or the name of your main branch
- feature/*

steps:
 # Checkout the repository
 - checkout: self

 # Disable shallow fetch
  fetchDepth: 0

# Prepare Analysis Configuration task
- task: SonarQubePrepare@6
  inputs:
    SonarQube: 'YourSonarqubeServerEndpoint'
    scannerMode: 'Other'
    extraProperties: 'sonar.projectKey=YourProjectKey'

# Publish Quality Gate Result task
- task: SonarQubePublish@6
  inputs:
    pollingTimeoutSec: '300'
.NET

Steps to construct your Azure pipeline for .NET

  1. In Azure DevOps, create or edit a Build Pipeline, and add a new Prepare Analysis Configuration task before your build task:
    • Select the SonarQube server endpoint you created in the Adding a new SonarQube Service Endpoint section.
    • Under Choose a way to run the analysis, select Integrate with MSBuild.
    • In the project key field, enter your project key.
  2. Add a new Run Code Analysis task after your build task.
  3. Add a new Publish quality gate Result on your build pipeline summary.
  4. Under the Triggers tab of your pipeline, select Enable continuous integration, and choose all of the branches for which you want SonarQube analysis to run automatically.
  5. Save your pipeline.

.yml example:

trigger:
- master # or the name of your main branch
- feature/*

steps:
 # Checkout the repository 
- checkout: self

 # Disable shallow fetch
  fetchDepth: 0

# Prepare Analysis Configuration task
- task: SonarQubePrepare@6
  inputs:
    SonarQube: 'YourSonarqubeServerEndpoint'
    scannerMode: 'MSBuild'
    projectKey: 'YourProjectKey'

# Dotnet build task
- task: DotNetCoreCLI@2
  displayName: 'dotnet build'

# Run Code Analysis task
- task: SonarQubeAnalyze@6

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

.Net guides on the Sonar Community forum

We’ve prepared some guides on the Community Forum to help you with your .NET project.

.NET Configuration

.NET and Code coverage

Other (JavaScript, TypeScript, Go, Python, PHP, etc.)

Steps to construct your Azure pipeline for other languages

  1. In Azure DevOps, create or edit a Build Pipeline, and add a new Prepare Analysis Configuration task before your build task:
    • Select the SonarQube server endpoint you created in the Adding a new SonarQube Service Endpoint section.
    • Under Choose a way to run the analysis, select Use standalone scanner.
    • Select the Manually provide configuration mode.
    • In the Project Key field, enter your project key.
  2. Add a new Run Code Analysis task after your build task.
  3. Add a new Publish quality gate Result on your build pipeline summary.
  4. Under the Triggers tab of your pipeline, select Enable continuous integration, and choose all of the branches for which you want SonarQube analysis to run automatically.
  5. Save your pipeline.

.yml example:

trigger:
- master # or the name of your main branch
- feature/*

steps:
 # Checkout the repository
 - checkout: self
 
 # Disable shallow fetch
   fetchDepth: 0

# Prepare Analysis Configuration task
- task: SonarQubePrepare@6
  inputs:
    SonarQube: 'YourSonarqubeServerEndpoint'
    scannerMode: 'CLI'
    configMode: 'manual'
    cliProjectKey: 'YourProjectKey'

# Run Code Analysis task
- task: SonarQubeAnalyze@6
  inputs:
    jdkversion: 'JAVA_HOME_17_X64'

# Publish Quality Gate Result task
- task: SonarQubePublish@6
  inputs:
    pollingTimeoutSec: '300'
Analyzing a C/C++/Obj-C project

Steps to construct your Azure pipeline for C family projects

In your build pipeline, insert the following steps in the order they appear here. These steps can be interweaved with other steps of your build as long as the following order is followed. All steps have to be executed on the same agent.

  1. Make the Build Wrapper available on the build agent: Download and unzip the Build Wrapper on the build agent (see the Prerequisites section of the C/C++/Objective-C page). The archive to download and decompress depends on the platform of the host. Please, note that:
    • For the Microsoft-hosted build agent, you will need to make the Build Wrapper available on the build agent every time (as part of the build pipeline). To accomplish this, you can add a PowerShell script task (on Windows) or a Bash task (on Linux and macOS) by inserting a Command Line task, and substituting the URL of your specific SonarQube instance into the download path below. 
      • Example of PowerShell commands on a Windows host:
        Invoke-WebRequest -Uri '<Your SonarQube URL>/static/cpp/build-wrapper-win-x86.zip' -OutFile 'build-wrapper.zip'
        Expand-Archive -Path 'build-wrapper.zip' -DestinationPath '.'
      • Example of bash commands on a Linux host:
        curl '<Your SonarQube URL>/static/cpp/build-wrapper-linux-x86.zip' --output build-wrapper.zip
        unzip build-wrapper.zip
      • Example of bash commands on a Linux ARM64 host:
        curl '<Your SonarQube URL>/static/cpp/build-wrapper-linux-aarch64.zip' --output build-wrapper.zip
        unzip build-wrapper.zip
      • Example of bash commands on a macos host:
        curl '<Your SonarQube URL>/static/cpp/build-wrapper-macosx-x86.zip' --output build-wrapper.zip
        unzip build-wrapper.zip
    • For the self-hosted build agent, you can either download it every time (using the same scripts) or only once (as part of the manual setup of your build agent).
  2. Add a Prepare analysis configuration task and configure it as follow: Click on the Prepare analysis on SonarQube task to configure it:
    • Select the SonarQube Server.
    • In Choose the way to run the analysis, select standalone scanner (even if you build with Visual Studio/MSBuild).
    • In Advanced section > Additional properties, add the property sonar.cfamily.compile-commands with, as its value, the path to the compile_commands.json file inside the Build Wrapper output directory: sonar.cfamily.compile-commands=<output directory>/compile_commands.json
  3. Add a Command Line task to run your build. For the analysis to happen, your build has to be run through a command line so that it can be wrapped-up by the build-wrapper. To do so,
    • Run Build wrapper executable. Pass in as the arguments: 
      1. The output directory configured in the previous task and 
      2. The command that runs a clean build of your project (not an incremental build):
        • Example of PowerShell commands on a Windows host with an MSBuild build:
          build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir <output directory> MSBuild.exe /t:Rebuild
        • Example of bash commands on a Linux host with a make build:
          build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir <output directory> make clean all
        • Example of bash commands on a Linux ARM64 host with a make build:
          build-wrapper-linux-aarch64/build-wrapper-linux-aarch64 --out-dir <output directory> make clean all
        • Example of bash commands on a macos host with a xcodebuild build:
          build-wrapper-macosx-x86/build-wrapper-macos-x86 --out-dir <output directory> xcodebuild -project myproject.xcodeproj -configuration Release clean build
  4. Add a Run code analysis task to run the code analysis and make the results available to SonarQube. Consider running this task right after the previous one as the build environment should not be significantly altered before running the analysis.
  5. Add a Publish quality gate result task.

Once all this is done, you can trigger a build.

You must choose the correct image and adapt the correct wrapper depending on the agent OS. See the example below to configure the correct wrapper.

.yml example:

trigger:
- master # or the name of your main branch
- feature/*

steps:
- checkout: self
  # disable shallow fetch
  fetchDepth: 0

# Make Build Wrapper available
- task: Bash@3
  displayName: Download Build Wrapper
  inputs:
    targetType: inline
    script: |
      curl  '<SONARQUBE_HOST>/static/cpp/build-wrapper-linux-x86.zip' --output build-wrapper.zip
      unzip build-wrapper.zip

# Prepare Analysis Configuration task
- task: SonarQubePrepare@6
  inputs:
    SonarQube: 'YourSonarqubeServerEndpoint'
    scannerMode: 'CLI'
    configMode: 'manual'
    cliProjectKey: 'YourProjectKey'
    extraProperties:  |
      "sonar.cfamily.compile-commands=bw_output/compile_commands.json"
# Command Line task to run your build.
- task: Bash@3
  displayName: Bash Script
  inputs:
    targetType: inline
    script: |
      ./build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir bw_output <Your build command>

# Run Code Analysis task
- task: SonarQubeAnalyze@6

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

Running your pipeline

Commit and push your code to trigger the pipeline execution and SonarQube analysis. New pushes on your branches (and pull requests if you set up pull request analysis) trigger a new analysis in SonarQube.

Maintaining pull request code quality and security

Using pull requests allows you to prevent unsafe or substandard code from being merged with your main branch. The following branch policies can help you maintain your code quality and safety by analyzing code and identifying issues in all of the pull requests on your project. These policies are optional, but they're highly recommended so you can quickly track, identify, and remediate issues in your code.

Ensuring your pull requests are automatically analyzed

Ensure all of your pull requests get automatically analyzed by adding a build validation branch policy on the target branch.

Preventing pull request merges when the quality gate fails

Prevent the merge of pull requests with a failed quality gate by adding a SonarQube/quality gate status check branch policy on the target branch.

Watch this video for a quick overview of how to prevent pull requests from being merged when they are failing the quality gate.

Reporting your quality gate status in Azure DevOps

After you've set up SonarQube to import your Azure DevOps repositories as shown in the Importing your Azure DevOps repositories into SonarQube above, SonarQube can report your quality gate status and analysis metrics directly to your Azure DevOps pull requests.

To do this, add a project from Azure DevOps by clicking the Add project button in the upper-right corner of the Projects homepage and select Azure DevOps from the drop-down menu.

Then, follow the steps in SonarQube to analyze your project. SonarQube automatically sets the project settings required to show your quality gate in your pull requests.

If you're creating your projects manually or adding quality gate reporting to an existing project, see the following section.

Reporting your quality gate status in manually created or existing projects

SonarQube can also report your quality gate status to Azure DevOps pull requests for existing and manually-created projects. After setting your global settings as shown in the Importing your Azure DevOps repositories into SonarQube section above, set the following project settings at Project Settings > General Settings > DevOps Platform Integration:

  • Project name
  • Repository name

Advanced configuration

Reporting your quality gate status on pull requests in a monorepo

Reporting quality gate statuses to pull requests in a monorepo setup is supported starting in Enterprise Edition.

In a monorepo setup, multiple SonarQube projects, each corresponding to a separate project within the monorepo, are all bound to the same Azure DevOps repository. You'll need to set up each SonarQube project that's part of a monorepo to report your quality gate status.

You need to set up projects that are part of a monorepo manually as shown in the Reporting your quality gate status in manually created or existing project section above. You also need to set the Enable monorepo support setting to true at Project Settings > General Settings > DevOps Platform Integration.

After setting your project settings, ensure the correct project is being analyzed by adjusting the Analysis Scope and pass your project names to the scanner. See the following sections for more information.

Ensuring the correct project is analyzed

You need to adjust the analysis scope to make sure SonarQube doesn't analyze code from other projects in your monorepo. To do this set up a Source File Inclusion for your project at Project Settings > Analysis Scope with a pattern that will only include files from the appropriate folder. For example, adding ./MyFolderName/**/* to your inclusions would only add code in the MyFolderName folder to your analysis. See the Analysis scope page for more information on setting your narrowing the focus of your analysis scope.

Passing project names to the scanner

Because of the nature of a monorepo, SonarQube scanners might read all project names of your monorepo as identical. To avoid having multiple projects with the same name, you need to pass the sonar.projectName parameter to the scanner. For example, if you're using the Maven scanner, you would pass mvn sonar:sonar -Dsonar.projectName=YourProjectName.

Configuring multiple DevOps platform instances

SonarQube can report your quality gate status to multiple DevOps platform instances. To do this, you need to create a configuration for each DevOps platform instance and assign that configuration to the appropriate projects.

  • As part of Developer Edition, you can create one configuration for each DevOps platform.
  • Starting in Enterprise Edition, you can create multiple configurations for each DevOps platform. 
Linking issues

When adding a quality gate status to your pull requests, individual issues will be linked to their SonarQube counterparts automatically. For this to work correctly, go to Administration > Configuration > General Settings > General > General to set the instance's Server base URL. Otherwise, the links will default to localhost.

Using the Prepare Analysis Configuration task

The Prepare Analysis Configuration task will configure all the required settings before executing the build. This task is mandatory. In the case of .NET solutions or Java projects, this task helps to integrate seamlessly with MSBuild, Maven, and Gradle tasks.

SonarQubePrepare task properties

These properties can be defined, should they be useful to your workflow:

Required properties

  • cliSources
    • Note: Path to the root directory containing source files. This value is set to the sonar.sources SonarQube property.
    • Default: .
  • configMode
    • Note: This property is required, but only needs to be modified if you specify the optional configFile property. Choose one of the options as your preferred configuration method. 
    • Options
      • file: Store configuration with my source code in sonar-project.properties
      • manual: Manually provide configuration mode
    • Default: file
  • projectKey or cliProjectKey
    • Note: The project’s unique key and the name that will be displayed on the web interface. Allowed characters are letters, numbers, -, _, ., and :, with at least one non-digit. The cli prefix shall be used only while running in cli scanner mode.
    • Default: <yoursonarqubeusername_yourprojectname>
  • scannerMode
    • Allowed values: MSBuild (Integrate with MSBuild), Other (Integrate with Maven or Gradle), CLI (Use standalone scanner). 
    • Default value: MSBuild
  • SonarQube Server Endpoint
    • To create a SonarQube server endpoint, click the Manage link, create a new SonarQube Server Endpoint, and enter your server URL and token.
    • Default: The name of the Service connection you created in Azure DevOps.

Optional properties

  • configFile
    • Note: The path to the file containing your SonarQube configuration. 
    • Default: sonar-project.properties
  • extraProperties
    • Note: Additional properties to be passed to the scanner. Specify each key=value pair on a new line. See the Analysis parameters and Analysis scope pages for more detail on optional parameters. 
    • Note: Put one key=value per line; for example: sonar.exclusions=**/*.bin
  • projectName or cliProjectName
    • Note: The name of the project that will be displayed on the web interface. The cli prefix shall be used only while running in cli scanner mode.
    • Default: For Maven projects: <name>; otherwise the projectKey
  • projectVersion or cliProjectVersion
    • Note: The project version and the version of the project displayed on the web interface.  The cli prefix shall be used only while running in cli scanner mode. Do not use your build number as the projectVersion.
    • Default: For Maven projects: <description>; otherwise, “not provided”.
  • msBuildVersion or cliVersion
    • Note: Optionally set these properties to override the embedded scanners with the specified versions. Use msBuildVersion to override the SonarScanner for .NET version, and cliVersion to override the SonarScanner CLI version.
    • Default: The active version of the SonarScanner for .NET or the SonarScanner CLI.


Troubleshooting

Self-signed certificate error on Prepare Analysis Configuration task

Try to add the server self-signed certificate as described in Adding the self-signed server certificate to the trusted CA certificates > If using Azure DevOps.

Missing build agent capability

Previously, there was a Microsoft bug related to having a Windows Build Agent with a non-oracle Java version installed on it; the agent failed to detect a needed capability for the SonarQube Azure DevOps plugin. It is reported that this bug is now solved.

If you still have problems and are sure that the java executable is available in the PATH environment variable, you can add the missing capability manually by going to your build agent > capabilities > user capabilities > add capability. Here, you can add the key, value pair java, and null which should allow the SonarQube plugin to be scheduled on that build agent.


Was this page helpful?

© 2008-2024 SonarSource SA. All rights reserved. SONAR, SONARSOURCE, SONARLINT, SONARQUBE, SONARCLOUD, and CLEAN AS YOU CODE are trademarks of SonarSource SA.

Creative Commons License