How to create Nuget Package for .Net Core

Yep! Another article about Nuget package creation. And you know why? It’s a pain in the ass (hou rude words for a shiny morning…).

When I discover Nuget packages I was really enthusiast. It’s look like Composer package. But not really…

You have to manage by hand all the dependencies. And that’s make me angry!

I’m a lazy developer, so how can I make easily a Nuget package, with just only one command line?

Follow me, I show you.

This article is based on my work on the GST.Library that is a .Net Core solution who hold some libraries. I’ve faced the problem of building multi Nuget package from one solution. We need to automate the build of each package and we need something to manage dependencies and cross dependencies of each project.

The solution file organisation:

| GST.Library.sln
|
+---artifacts
| GST.Library.API.REST.1.0.0.nupkg
| GST.Library.API.REST.1.0.0.symbols.nupkg
|
+---src
| +---GST.Library.API.REST
| | | GST.Library.API.REST.nuspec
| | | project.json
| | |
| | +---Annotations
| | \---Pagination
| |
| +---GST.Library.Data
| | | GST.Library.Data.nuspec
| | | project.json
| | |
| | \---Extentions
| |
| +---GST.Library.Helper
| | | GST.Library.Helper.nuspec
| | | project.json
| | |
| | \---Type
| |
| \---GST.Library.StoredProcedureHelper
| | GST.Library.StoredProcedureHelper.nuspec
| \ project.json
|
+---test
\---tools

First of all, we are using Cake (for once cake is not a lie)! Cake is a task runner like Grunt, but made for Windows stuff, like building .Net Core application or C# DSL. What is nice with Cake, that it is cross platform application (you can use it on Linux).

To use Cake, we have to copy two (or one file) from their Github repo https://github.com/cake-build/example.

Take `build.ps1` for running with Powershell or `build.sh` for running with bash.

These two files contains the code for installing Cake, if it’s not, and running the `build.cake` file who will contain all our needed tasks to build Nuget packages.

Now you have to create a `build.cake` file and put this code inside :

#tool "nuget:?package=xunit.runner.console"
//////////////////////////////////////////////////////////////////////
// ARGUMENTS
//////////////////////////////////////////////////////////////////////

var target = Argument("target", "BuildPackages");
var configuration = Argument("configuration", "Release");

//////////////////////////////////////////////////////////////////////
// PREPARATION
//////////////////////////////////////////////////////////////////////

// Define directories.
var artifactsDir  = Directory("./artifacts/");
var rootAbsoluteDir = MakeAbsolute(Directory("./")).FullPath;

//////////////////////////////////////////////////////////////////////
// TASKS
//////////////////////////////////////////////////////////////////////

Task("Clean")
    .Does(() =>
{
    CleanDirectory(artifactsDir);
});

Task("Restore-NuGet-Packages")
    .IsDependentOn("Clean")
    .Does(() =>
{
	DotNetCoreRestore("src");
});

Task("BuildPackages")
    .IsDependentOn("Restore-NuGet-Packages")
    .Does(() =>
{
	var rootAbsoluteDir = "./build/bin";
    var nuGetPackSettings = new NuGetPackSettings
	{
		OutputDirectory = rootAbsoluteDir + @"\artifacts\",
		IncludeReferencedProjects = true,
		Properties = new Dictionary<string, string>
		{
			{ "Configuration", "Release" }
		}
	};

	var settings = new DotNetCoreBuildSettings
     {
         Framework = "netcoreapp1.1",
         Configuration = "Release",
         OutputDirectory = "./artifacts/"
     };

	DotNetCoreBuild("./src/**/project.json", settings);

	var packageSettings = new DotNetCorePackSettings
     {
         Configuration = "Release",
         OutputDirectory = "./artifacts/"
     };

    // For each project that we want to packaged
    DotNetCorePack("./src/GST.Library.API.REST/", packageSettings);
    DotNetCorePack("./src/GST.Library.Data/", packageSettings);
    DotNetCorePack("./src/GST.Library.Helper/", packageSettings);
    DotNetCorePack("./src/GST.Library.StoredProcedureHelper/", packageSettings);
});


//////////////////////////////////////////////////////////////////////
// EXECUTION
//////////////////////////////////////////////////////////////////////

RunTarget(target);

We have one more things to do. That’s the hard part. You have to install Nuget on your system (and add it to your environment variable) or just download the nuget.exe and put it in your project folder.
Now open a Terminal (Powershell console) and write : `nuget spec`
With this command line Nuget will create a ` Package.nuspec` file. This file is the manifest of your package.
Please take time to read the official documentation. But don’t waste time on the dependencies part. Our Cake script will take care to fill-up dependencies for us. We don’t have to do this manually, and that’s the real comfort to use automation.

You can take a look at our github repository https://github.com/GestionSystemesTelecom/gst-library , you will have a real world example. This repository is tie with Appveyor, and every time we push code on that repo, Appveyor compile and push nuget packages to nuget.org.

For the GST.Library, I wanted that each project would be a Nuget package. By putting in each project a “.nuspec” file and using Cake automation, I can easily create multi Nuget package.

Thanks to this blog post to show me the way: https://blog.codeinside.eu/2017/02/13/create-nuget-packages-with-cake/

Publié dans .Net Core

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*