Integrating SonarQube with Azure DevOps
Enhance your Azure DevOps pipeline with a focus on code quality and security. This practical guide provides a detailed walkthrough of integrating SonarQube with Azure DevOps, including actionable code snippets. Discover how to leverage SonarQube’s automated code analysis capabilities to identify and resolve issues early, ensuring only high-quality code makes it to production.
Prerequisites:
Deploying community edition using Helm
Authenticate to your cluster from CLI and deploy community edition using helm and run the following commands to install helm chart:
helm repo add sonarqube https://SonarSource.github.io/helm-chart-sonarqube
helm repo update
kubectl create namespace sonarqube
helm upgrade --install -n sonarqube sonarqube sonarqube/sonarqube
Configure your ingress once deployed. This will be later used to create Azure DevOps service connection and accessing SonarQube dashboard.
Integrate with Azure DevOps Pipelines
Add SonarQube Extension to your Azure DevOps organization from marketplace
1. Add a new SonarQube Service Connection
- In Azure DevOps, go to Project settings > Service connections
- Add a new service connection of type SonarQube
- Enter your SonarQube server url:https://your.kubernetes.ingress.com
- Enter an existing token, or a newly generated token from sonar dashboard SonarQube dashboard > Administration > Users > Tokens
- Enter a memorable connection name.
- Create the service connection.
2. Configure Azure DevOps pipelines
In Azure DevOps, add Sonar Analysis stage to your pipeline.
SonarQubePrepare@7 task sets up the pipeline to analyze. This prepares the environment by configuring authentication, specifying the SonarQube project details and initializing necessary build variables.
- task: SonarQubePrepare@7
inputs:
SonarQube: "service_connection_name"
scannerMode: "cli"
configMode: "manual"
cliProjectKey: "unique projectkey [pipeline name]"
cliSources: "$(System.DefaultWorkingDirectory)/"
SonarQubeAnalyze@7 task performs the actual static code analysis of your project using SonarQube Scanner, it processes the source code and collects the metrics.
- task: SonarQubeAnalyze@7
inputs:
jdkversion: "JAVA_HOME_17_X64"
SonarQubePublish@7 task is the final step in SonarQube analysis process. It retrieves the analysis results from the SonarQube server and displays them in Azure DevOps pipeline summary, the detailed report can be viewed on SonarQube dashboard.
- task: SonarQubePublish@7
inputs:
pollingTimeoutSec: "300"
3. Code Coverage
It’s a critical aspect of maintaining code quality during software development. It measures the percentage of your code that is covered by automated tests, helping teams identify untested parts of codebase.
Use the following snippet if you have to include your coverage reports in sonar analysis.
- task: SonarQubePrepare@7
inputs:
SonarQube: "service_connection_name"
scannerMode: "cli"
configMode: "manual"
cliProjectKey: "unique projectkey [pipeline name]"
cliSources: "$(System.DefaultWorkingDirectory)/"
extraProperties: |
sonar.projectVersion=1.0
sonar.sources=$(System.DefaultWorkingDirectory)/
sonar.python.coverage.reportPaths=$(System.DefaultWorkingDirectory)/coverage.xml
sonar.exclusions=**/test/**
Make sure you add a task/stage which installs necessary libraries, run tests on your application and generate coverage report before the above task.
For more details refer documentation
Here’s everything from above compiled into one stage
# Run tests and create coverage report
# ...
- stage: SonarAnalysis
jobs:
- job: test
continueOnError: false
steps:
- task: SonarQubePrepare@7
inputs:
SonarQube: "service_connection_name"
scannerMode: "cli"
configMode: "manual"
cliProjectKey: "unique projectkey [pipeline name]"
cliSources: "$(System.DefaultWorkingDirectory)/"
extraProperties: |
sonar.projectVersion=1.0
sonar.sources=$(System.DefaultWorkingDirectory)/
sonar.python.coverage.reportPaths=$(System.DefaultWorkingDirectory)/coverage.xml
sonar.exclusions=**/test/**
- task: SonarQubeAnalyze@7
inputs:
jdkversion: "JAVA_HOME_17_X64"
- task: SonarQubePublish@7
inputs:
pollingTimeoutSec: "300"
# Build stage
# ...
Note: If you are using SonarQube Community Edition at the time of writing this article, SonarQube extension from Azure DevOps marketplace includes a variable in pipeline task (sonar.branch.name) which is not supported by community edition so as a result your pipelines would fail. So as a workaround in this case is to add a PowerShell after SonarQubePrepare@7 task, this will remove this variable.
- task: PowerShell@2
inputs:
targetType: "inline"
script: |
$params = "$env:SONARQUBE_SCANNER_PARAMS" -replace '"sonar.branch.name":"[\w,/,-]*"\,?'
Write-Host "##vso[task.setvariable variable=SONARQUBE_SCANNER_PARAMS]$params"
Build Validation
Build validation is a critical step in CI/CD where the code is analyzed and tested before it’s merged into production branch. By running validations in this manner, you can enforce quality gates and block changes that don't meet your organizations code quality standards.
Build validation will trigger sonar pipeline when a pull request is raised. Pull request will be merged only if this pipeline succeeds.
I recommend creating a separate pipeline with SonarAnalysis in your main branch to trigger during build validation.
Steps to add build validation to your branch:
- Open build validation Repos > Branches > click more options for the branch want to add validation > Branch policies > Policies
- Build Validation > Add new build policy
- Select Sonar-Validation pipeline
- Trigger: Manual
- Policy requirement: required
- Save
Note: To use SonarQube with build validation, you need SonarQube Developer Edition
Thank you for reading! If you found this guide helpful or have any questions, feel free to connect with me on LinkedIn!