When adding features to a project in Visual Studio, you can do so by directly referencing the libraries as individual dlls or a collection of dlls as a NuGet package. The advantage of using the NuGet package system is that it makes it easier to maintain the libraries. It notifies you if the added packages received an update and it also removes the files and related references if the libraries are no longer needed in that project. You (the developer) don’t have to track the files that the NuGet package added or place these in special folders or make sure they get copied in your builds. So what is NuGet?

NuGet is the package manager for the Microsoft development platform including .NET. The NuGet client tools provide the ability to produce and consume packages. The NuGet Gallery is the central package repository used by all package authors and consumers.

A NuGet package itself is nothing but a zip file – with the relevant libraries (dlls), a manifest file and in some cases, other supporting files. You can even download a NuGet package (.nupkg file) to your computer and rename it as a .zip file and treat it like a zip file from that point forward. NuGet.org acts as the central repository for hosting NuGet packages with over 100,000 packages. However, hosting on nuget.org means your packages are hosted publicly. This may not always be ideal because in some cases you may have libraries that contain proprietary code or algorithms that your software may want to leverage for competitive advantage.

This is where Azure DevOps comes in – you can host private NuGet packages using Azure DevOps artifacts. This is not restricted to NuGet packages only but also other types of packages for npm, Python, Maven and so on. Azure Pipelines allows you to publish and consume many different types of packages and artifacts. Additionally, you can use build artifacts and pipeline artifacts to help store build outputs and intermediate files between build steps. You can then add onto, build, test, or even deploy those artifacts.

Note: Pipeline artifacts is currently In Preview but are the next generation of managing Build artifacts.

So, the next logical question is, let’s say you have a class library in .NET Core, how do you publish and consume these as private NuGet packages?

Option 1: YAML it

Add the following snippet to your azure-pipelines.yml file

- task: NuGetCommand@2
  inputs:
    command: pack
    packagesToPack: '**/*.csproj'

Option 2: Use NuGet tasks

Option 3: Use .NET Core tasks

In my experience, I prefer using the .NET Core tasks (Option 3) over the NuGet tasks (Option 2) because the NuGet specific tasks can get really tricky based on the version of NuGet,

What about versioning?

A NuGet package is always referred to using its package identifier and an exact version number. For example, NuGet packges for Entity Framework on nuget.org has several dozen specific packages available, like version 4.1.10311, 6.1.3, and a variety of pre-release versions like 6.2.0-beta1. A recommended approach to versioning packages is to use Semantic Versioning. Semantic version numbers have three numeric components, Major.Minor.Patch.  When you create a package in continuous integration (CI), you can use Semantic Versioning with prerelease labels. Some common formats are:

  • Use auto-versioning provided by the Azure DevOps pipeline – use this scheme if you’re brand new to NuGet packages and Azure DevOps
  • Create your own custom versioning scheme – use this scheme if you already have an in-house versioning scheme
  • Feed major, minor and patch release numbers as variables in Azure DevOps pipeline and use current DateTime stamp $(Major).$(Minor).$(Patch).$(date:yyyyMMdd) – use this scheme if your software packages have daily/periodic releases
  • Feed major and minor release numbers as variable in Azure DevOps pipeling and auto-incremement build and package numbers $(Major).$(Minor).$(rev:.r) –  recommended for most cases
How and where do I host and consume these packages?

For private hosting, these NuGet packages can be published to Azure Artifacts from the Publish task of the pipeline.

These NuGet packages can then be consumed in Visual Studio by adding them as a package source.

Since I’m publishing and hosting code, how do I debug issues with these packages?

Symbol servers enable debuggers to automatically retrieve the correct symbol files without knowing product names, build numbers, or package names and allows debugging of NuGet packages using Visual Studio (for best results, use newer versions of Visual Studio 2017). This can be accomplished with the “Index Sources & Publish Symbols” task in the pipeline to publish symbols to the Package Management symbol server or a file share. Indexing source code enables you to use symbol (.pdb) files to debug an app on a machine other than the one used to build the app.

In summation:

You can create and host your libraries as private NuGet packages using Azure DevOps. This approach provides you the flexibility of not only publishing your packages as part of a CI/CD pipeline but also perform versioning, hosting and debugging.

If your software team is interested in learning more about the intricacies of hosting your own private NuGet feeds on Azure DevOps or other custom software development solutions, contact our Nebbia Technology team. We also have in-house experts in Azure, DevOps, databases and .NET and web development to assist with the effort.