Adding SourceLink and coverage reports to your open source library with help from NukeBuild, AzureDevOps and Coverlet SleepyManiac Follow Jan 19, 2019 · 3 min read

This is a second part of publishing your open source library to nuget series. The first part could be found here.

SourceLink

SourceLink allows the developers to have a better dev experience by allowing you to debug through the third party code in the same way as you would debug through your own (with much better breakpoint support). Visual Studio, Jetbrains Rider and VSCode all support SourceLink now. You can read more about it here.

To add sourcelink support to your library you have to do the following:

Add some optional properties to your csproj file (you may read about them in SourceLink github repo

<PublishRepositoryUrl>true</PublishRepositoryUrl>

<EmbedUntrackedSources>true</EmbedUntrackedSources>

<IncludeSymbols>true</IncludeSymbols>

<SymbolPackageFormat>snupkg</SymbolPackageFormat>

2. Add a reference to you repo provider specific nuget package. E.g. for github, add

<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-18618-05" PrivateAssets="All"/>

That’s it! Now when building the nuget package, you will get 2 packages (one with dll files and one with debug symbols. You have to publish them both to nuget (just upload the files one by one). After doing so, on nuget you should be able to see that both the main package and symbols package are downloadable:

The last part is verifying that SourceLink information is indeed embeded in the package. One way of doing it is using the fuget. Fuget is a nuget browser with some extended functionality, which allows you to view more metadata of the package. To open the package on fuget.org you can simply replace the nuget with fuget in uri (e.g. for https://www.nuget.org/packages/Newtonsoft.Json/ you need to open https://www.fuget.org/packages/Newtonsoft.Json/). Search is also available.

If the SourceLink information is included, you should see a link to source at the top:

This link points to the exact git commit hash which was used for building the project.

Adding coverage report

There are many ways of doing coverage in .net core projects. The free cross-platform options include coverlet and altcover. When running on windows you may also try DotCover.

For this guide, I will use coverlet.

Add a reference to coverlet.msbuild nuget package.

<PackageReference Include="coverlet.msbuild" Version="2.5.0" />

2. In the nuke build project, add the necessary coverlet properties to Test task. E.g.

In this sample, we include SourceLink links to the original repo for reports to use (if not used, it will use absolute file paths instead).

Now let’s add a task to publish the coverage result to Azure DevOps

- task: PublishCodeCoverageResults@1

inputs:

codeCoverageTool: "cobertura"

summaryFileLocation: "$(Build.SourcesDirectory)/artifacts/coverage/*.xml"

failIfCoverageEmpty: true

displayName: 'Publish Code Coverage'

You may also consider adding an HTML report which can be published to Azure DevOps as well. If you’re interested in this functionality, you may be interested in ReportGenerator project.

If everything was done correctly, you should be able to the the coverage information on Azure DevOps build results page

Badges

In the previous post, I’ve described adding build status badge to your repo. However, this badge only shows the status of the build, without details. Luckly there is a wonderful service shields.io which allows you to find and add badge for about any scenario (including test and coverage statistics). Below is an example from my repo.

[![Test results](https://img.shields.io/azure-devops/tests/DzmitrySafarau0213/NodaTime.Serialization.Utf8Json/1.svg)](https://dev.azure.com/DzmitrySafarau0213/NodaTime.Serialization.Utf8Json/_build?definitionId=1?branchName=develop) [![Coverage results](https://img.shields.io/azure-devops/coverage/DzmitrySafarau0213/NodaTime.Serialization.Utf8Json/1/develop.svg)](https://dev.azure.com/DzmitrySafarau0213/NodaTime.Serialization.Utf8Json/_build/latest?definitionId=1?branchName=develop)

I recomment you to refer to documentation on shields.io, it’s really easy and straightforward.

You may refer to the full sample library I’ve used as a reference for any extra details https://github.com/DSilence/NodaTime.Serialization.Utf8Json