After my previous post about using Azure DevOps as a buildserver I am going to show you what else you can do with it. The second thing we are going do with it is create a NuGet package and publish it through Azure Pipelines. Read on if you want to know more about his.
Now that you know what we are going to do i’ll give you a short introduction about NuGet packages after that we dive into how we can create these in azure devops. Because we are developers we always start counting at zero instead of 1.
Step 0: What are NuGet packages?
NuGet packages are a way to allow developers and library creators to share their code and give them a system that they can use to give add some structure about updating their libraries and keeping versioning intact. It is basically a zip file (with another extension) and a standard folder structure where your library (dlls) are stored. Metadata about that library is stored in a NuSpec xml file (for .net framework packages) or in the .csProj file. The NuSpec properties allows you to add a description, version and name to your custom NuGet package amongst other things. A empty .net(core) type project comes with a lot of different NuGet packages. Most of them are stored on NuGet.org, however you can host your own NuGet feed in Azure DevOps or any other place you want. This can be used to release packages to only a limited audience, such as your organization or workgroup.
Step 1: Something about versioning
As explained before NuGet packages have a version it is important to keep your versioning correct. If you don’t then you create a lot more work for the developers that use it because they get something they didn’t expect. A specific NuGet version number is in the form Major.Minor.Patch[-Suffix], where the components have the following meanings:
- Major: Breaking changes (ie: after updating my code stops compiling)
- Minor: New features, but backwards compatible
- Patch: Backwards compatible bug fixes only
- -Suffix (optional): a hyphen followed by a string denoting a pre-release version. (This can be -beta, -alfa etc)
To give an example of how this version increases through time we’ll start with version “1.0.1”. After doing some work on the package I release a new beta version which is labelled “1.2.0-beta”. (Please note the 2 in the minor version number). After testing and fixing bugs i’ll release it as stable with version “1.2.0” (not beta anymore). However after creating this package my library completely changes and then I would create a “2.0.0-beta” which after becoming stable will become version “2.0.0”.
So what happens when you do it wrong? Increasing minor instead of major version causess a user of your library to get breaking changes to their code without any advance notification. They need to do more work to make everything right again. More information about versioning of NuGet packages can be found here.
Step 2: Create a solution
For this example we are using .net core/standard as stated above. You can also do this using .net framework but some small changes have to be made.

So after that we need to some implementation. I’ve named my solution “DemoLoggerPackage” so that’s what we are gonna create. I added added the following code:
namespace DemoLoggerPackage { public enum LogSeverity { Unknown = 0, Waring = 1, Error = 2, Info = 3, } public class Logger : ILogger { public void Log(string message, LogSeverity severity, Exception ex = null) { } } public interface ILogger { void Log(string message, LogSeverity severity, Exception ex = null); } }
To look/change at the information from the NuSpec file we go to “projects”, “Properties”.

You can change the data in these fields according to your needs. More information about hem can be found here.
Step 3:Create a NuGet feed to host our pacakges
We have create some code in a project however we need to create a NuGet feed somewhere to host our own packages. We choose the “Artifacts” option from Azure Devops and create a new feed. We just leave the settings default.

Step 4: Push the code to Azure DevOps and create a package build
We now have created a NuGet package and a NuGet feed. We first need to push to to to a repository in Azure DevOps. Then we go to our “Pipelines” and add a new build

We select “Azure Repos GIT” and select our team project, repository and branch which we want to use. After pressing continue we select “ASP.net Core” as our default template. We use this because it best suits our requirements.

The default build is shown below. We however don’t need the steps 4 and 5 so we remove them.

After removing steps 4 and 5 we need to add a new step. The first step we need is a “Package” step. We add a .net core Task which we name “Pack”. We configure it like this:

To give a little more explanation about the configuration I’ve numbered the important parts:
- The step name which is used in the list on the left hand side of the page.
- The command that has to be run “dotnet pack” in this case
- The project we want to package. If you only have one in your solution you can leave it default
- With regards to versioning we use a manual version in this example. We select and environment variable that we use for this.
- The name of the environment variable to use
When executing this build you can change the variable to the value you want by configuring it like you can see below:

Step 5: Publish the package on a package source
After the the package step has been completed we have successfully created a NuGet package. However we want to be able to use it from a project so we need to add the last step that publishes our new package to a package source. The last step is the publish step. The configuration can be seen below:

- The name of the step
- The command to use “dotnet nuget push”
- The package feed you want to use. You can also configure another external server but by using Azure Artifacts a lot of the hard work is done for you.
After running this build you’ll see a NuGet package being published to your NuGet feed. It looks like this on the feed details:

As you can see our fancy new package is added here with the version number we added as an environment variable.