SonarCloud is the hosted version of the popular SonarQube code quality tool from SonarSource that provides tooling to analyse code for quality, vulnerabilities and bugs.
The main features of SonarCloud are:
- 16 languages: Java, JS, C#, C/C++, Objective-C, TypeScript, Python, ABAP, PLSQL, T-SQL and more.
- Thousands of rules to track down hard-to-find bugs and quality issues thanks to powerful static code analyzers.
- Cloud CI Integrations, with Travis, VSTS, AppVeyor and more.
- Deep code analysis, to explore all source files, whether in branches or pull requests, to reach a green quality gate and promote the build.
- Fast and Scalable
SonarCloud is free for Open Source projects however offer a range of paid plans to suit your individual needs. If you wish to host yourself, you can use SonarQube in your on-prem environment and once installed the steps should be similar to those we will cover using SonarCloud in this post.
First up (if using SonarCloud approach) you will want to login to SonarCloud and create a new project. You can login using your GitHub or Azure DevOps account, once you have authenticated and have an account setup on SonarCloud, you will be prompted to create your first project.
Provide a project key and display name then click ‘Setup’. The project key and name will be used to link our pipeline to our SonarCloud project.
Once setup we are now ready to update our pipeline to run our static analysis and send our results to SonarCloud.
To install the SonarCloud extension ready for inclusion in our pipeline, go to the extension page here and click ‘Get it free’
You may be prompted to login, then select the Azure DevOps organisation you wish to install the extension into
Once installed you can click ‘Proceed to organisation’
We are now ready to update our pipeline. As of writing this blog post, documentation for adding SonarCloud to YAML pipelines is pretty limited, however build templates are in the works.
I found the easiest way to get started from scratch was to create a new pipeline using the ‘Visual Designer’ and configuring the SonarCloud plugins that way. Once configured, you can view the YAML for this pipeline and copy the neccessary parts out into your own YAML pipeline. I have found this approach useful when using extensions that don’t provide much in terms of documentation. If anyone has a link to documentation the covers a YAML first configuration for SonarCloud, drop me a comment at the bottom and I will update.
Ok, lets setup a temporary pipeline using the Visual Editor to configure our SonarCloud extensions and get the necessary YAML for our pipeline.
From our Azure DevOps portal, under ‘Builds’ for our project, click ‘New’ and ‘New Build Pipeline’
This time however, we want to choose the option ‘Use the visual designer’ at the bottom
Select GitHub and your repository when prompted and continue
Select the Asp.Net template (not YAML under configuration as code) and click apply.
The template will have some default tasks already populated. Highlight them all, then right click and ‘Remove selected task(s)’
Our temporary pipeline is now ready to configure our SonarCloud tasks.
Click the plus icon beside the Agent Job, search for SonarCloud then add the 3 tasks that are returned.
Once they are added, you will notice the task ‘Prepare analysis on SonarCloud’ has some settings that need attention. Click the task and it will open the configuration screen for the task
Click ‘New’ beside ‘SonarCloud Service Endpoint’ that will open a dialog, enter a connection name and a SonarCloud token, which can be obtained from the SonarCloud portal here
Give your token a name (eg vsts_build), click generate then finally click copy
Now your token has been generated, back in Azure DevOps paste it into the SonarCloud Token box and click ‘Verify connection’. If all looks good, finally like ‘Ok’
Next select your Organisation and paste in your SonarCloud project key that you created earlier. These can also be found from the SonarCloud portal under your project overview page
Finally enter your SonarCloud project name. The final configuration should look similar to the following
Now that our configuration is complete, we just need to copy the generated YAML into our existing pipeline. Click on the Agent Job (rather than having a single task selected) then click on ‘View YAML’ then finally copy to clipboard.
We only need the 3 tasks from the YAML file, so paste the yaml content into notepad then return to VS Code and open the ‘azure-pipeline.yml’ file in the root of your project.
Paste the ‘Run Code Analysis’ task in as the first step in our pipeline. Place ‘Prepare analysis on SonarCloud’ followed by ‘Publish Quality Gate Result’ tasks after the ‘PublishTestResults@2’ task
Your final YAML file should look like the following (with your own SonarCloud configuration)
# ASP.NET Core
# Build and test ASP.NET Core projects targeting .NET Core.
# Add steps that run tests, create a NuGet package, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core
pool:
vmImage: 'VS2017-Win2016'
variables:
buildConfiguration: 'Release'
projectName: 'TwitterSentiment'
steps:
- task: SonarSource.sonarcloud.14d9cde6-c1da-4d55-aa01-2965cd301255.SonarCloudPrepare@1
displayName: 'Prepare analysis on SonarCloud'
inputs:
SonarCloud: SonarCloud
organization: 'steven-knox24260'
projectKey: 'twitter-sentiment-juihdfewuirye87t34ui587'
projectName: 'Twitter Sentiment Analysis'
- script: |
dotnet build $(projectName)/$(projectName).csproj --configuration $(buildConfiguration)
dotnet build $(projectName).Tests/$(projectName).Tests.csproj --configuration $(buildConfiguration)
dotnet test $(projectName).Tests/$(projectName).Tests.csproj --configuration $(buildConfiguration) --logger trx
dotnet publish $(projectName)/$(projectName).csproj --configuration $(buildConfiguration) --output $BUILD_ARTIFACTSTAGINGDIRECTORY
displayName: 'Build & Test'
- task: PublishTestResults@2
inputs:
testRunner: VSTest
testResultsFiles: '**/*.trx'
- task: SonarSource.sonarcloud.ce096e50-6155-4de8-8800-4221aaeed4a1.SonarCloudAnalyze@1
displayName: 'Run Code Analysis'
- task: SonarSource.sonarcloud.38b27399-a642-40af-bb7d-9971f69712e8.SonarCloudPublish@1
displayName: 'Publish Quality Gate Result'
- task: DotNetCoreCLI@2
displayName: 'dotnet pack'
inputs:
command: pack
nobuild: true
projects: '$(projectName)/$(projectName).csproj'
versioningScheme: byPrereleaseNumber
versionEnvVar: byPrereleaseNumber
majorVersion: 0
minorVersion: 1
patchVersion: 0
- task: DotNetCoreCLI@2
inputs:
command: 'push'
nuGetFeedType: 'internal'
packagesToPush: '$(build.artifactStagingDirectory)/*.nupkg'
publishVstsFeed: "WholeschoolPackages"
publishFeedCredentials: WholeschoolPackagesAuth
- task: PublishBuildArtifacts@1
SonarCloud also requires any projects that you wish to be analysed to contain a Project Guid in the .csproj file. To do this open TwitterSentiment.csproj and add a ProjectGuid element alongside the TargetFramework. You can generate a GUID online here. Your project file should now look like
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<ProjectGuid>{e0852829-b846-4b7e-a5d4-4dd978db1865}</ProjectGuid>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
</ItemGroup>
</Project>
The last thing we need to do to test our new pipeline step and analyse our code is push our changes to Github.
Return to your command line, navigate to the root of your project and commit your new changes.
git add .
git commit -m "Update pipeline for SonarCloud analysis"
git push
Our CI/CD pipeline should be triggered and once completed, we should see the results of our analysis in the SonarCloud portal. Note if you encounter an error similar to
Step input publishFeedCredentials references service connection WholeschoolPackagesAuth which could not be found. The service connection does not exist or has not been authorized for use. For authorization details, refer to https://aka.ms/yamlauthz
Follow the steps found in part 4 of this blog post series which shows how to save the pipeline in the Azure DevOps portal and activate the Service Connection.
Once the build passes successfully, navigate to SonarCloud and you should now see the results of anaysis for your project
We have now created a .NET Core library, setup a CI/CD pipeline to build, test and package our library, run static analysis to check for vulnerabilities, bugs and code quality then pushed our package to a private NuGet feed on Azure Artifacts ready for use in other projects.