Building a CI/CD pipeline for nuget package.
--
Getting started
So, you’re willing to publish your fist ever super awesome library as nuget package? Worry not, in this guide I will help you
Creating a repository
Let’s start off by creating a github repository. On github web interface, find New button. From there, enter a new repository name and choose a license (e.g. MIT). Github does not have a default .gitignore for .net projects, so leave it empty for now.
Starting up your project
Next thing we need to do is cloning the newly created repository. (You may use “git clone {repouri}”). First thing we need to do is creating a .gitignore for our project. The easyest way is just copying the file from another open source project (e.g. https://github.com/aspnet/EntityFrameworkCore/blob/master/.gitignore)
Now we can finally copy the library code to the repository. I prefer to put the source code in a “src” directory, but it’s entirely up to you.
For an open source library, you should strongly consider adding SourceLink support https://github.com/dotnet/sourcelink. This allows other developers to debug through your code.
Versioning
Versioning is very hard! If you are not fancy manually versioning each and every package, I suggest using automated tools for that. The best tool I’ve been working with is https://gitversion.readthedocs.io/en/latest/. This small command line tool parses the tags and branch information and is capable if incrementing the versions on it’s own! It requires zero configuration, but should you really need to adjust some values, you may place a config file to the root of your repository. In the next section, I will show you how to integrate this tool into CI/CD pipeline.
CI/CD pipeline
I personally think that the whole CI/CD process (outside of CI vendor-specific tasks) should be fully reproducible locally. Therefore, I recommend defining build steps using either Cake (https://github.com/cake-build/cake) Fake (https://github.com/fsharp/FAKE) or Nuke(https://github.com/nuke-build/nuke). I personally prefer Nuke, for it’s incredible integration with IDE and outstanding CLI tools. To get started with NUKE:
- Install nuke global tool (dotnet tool install -g Nuke.GlobalTool)
- From the root folder of your repository, execute “nuke :setup”
- Follow the prompts on the screen. Make sure to include GitVersion setup.
After you go through the setup process, you should be able to see a new project appear in your solution. And it already has some steps defined for you!
There is some customization required. You need to include the pack target for creating a nuget package and include reporting of test results. You may also want to create a target that combines the other targets in a pipeline to be called by the CI tool. A sample with those commands could be found in my repository here.
Now, commit all the changes to source control and let’s add the Azure Pipelines integration.
- Create a new project in Azure Pipelines. Use may want to you public project type for your open source project.
- Create a new pipeline. In the location, choose Github. Hit authorize button to authorize yourself on Github, and then choose a project.
- Next, edit a pipeline file. Since in our case we use Nuke to build our project, you only need to call nuke for all the build process, and then you can just use publish artifact steps to publish your artifacts
- You are done! The sample pipeline file could be found below. It will automatically trigger the build on branches specified.
Add a badge to you github repo. From the build pipeline, hit the 3 dots menu and choose StatusBadge button.
This will open a page with MD preset. Include this into your Readme.MD that can be found in the root of your repository.
Publishing to nuget
First, if you’ve done everything according to the samples provided, you can trigger the build on Azure DevOps and the resulting nuget packages will be available in the build artifacts
Download the package and go to nuget.org. Find the upload button and simply drag and drop the nupkg file. Your package will go through validation process, and after it finishes it should be available for download. That’s it!