64

Recently, I started to pack nuget packages out of my several projects. First I started with the Package Explorer application. It is a nice tool, but it's less useful if you do continuous integration. Then I looked into specifying the nuspec template file, and passing changing data, e.g. version number, as command line arguments. Later, I wondered how to define the nuget package dependencies. As it turns out, the nuget.exe already does this based on the package.config if you specify a csproj. Moreover, it extracts relevant data like Author, Version, Copyright right from the assembly info. What I'm missing right now is the ability to specify a licenseUrl in the command line. But I wanted the question to be more generic. And so I'm asking:

What is the prefered way to pack nuget packages?

manojlds
  • 290,304
  • 63
  • 469
  • 417
Matthias
  • 15,919
  • 5
  • 39
  • 84

4 Answers4

103

Here's a little-known fact: you can combine both! Target a csproj file, and make sure there's a nuspec file in the same directory with the same name as the csproj file. NuGet will merge the two during package creation.

So in short: target <ProjectName>.csproj, optionally add a corresponding tokenized <ProjectName>.nuspec file to be used as metadata by NuGet.exe.

It saves you from managing output location, dependencies, version, and other stuff that can be derived from the project.

Xavier Decoster
  • 14,580
  • 5
  • 35
  • 46
  • Hi Xavier, thanks for pointing this out :) I already found this [blog post](http://blog.davidebbo.com/2011/04/easy-way-to-publish-nuget-packages-with.html) which also suggest this approach. Is this also described in the book I got from you on the WarmCrocConf?;) Great presentation btw!;) – Matthias Feb 11 '13 at 14:57
  • Hi Matthias, thank you! If I'm not mistaken, it is mentioned on page 71 :) – Xavier Decoster Feb 11 '13 at 18:22
  • 3
    is it possible to get the version from the assemblyinfo AND have a nuspec? i do want the nuspec author and releasenotes bits, but it seems then i'd have to handle the version tag in the nuspec as well as the assemblyinfo – John Korsnes Jan 27 '15 at 04:25
  • 3
    @JohnKorsnes you tried using the nuspec with prepopulated values for author and releasenotes etc, whilst leaving the version tag tokenized? ($version$) – Xavier Decoster Jan 29 '15 at 17:20
  • I believe I only tried omitting it, but that did not help (as the pack fails). Will see if leaving it tokenized helps – John Korsnes Jan 30 '15 at 19:54
  • A note for those using Mono, NuGet.exe doesn't support packing by targeting a csproj (as of 3.3). There's plans to make it happen though. https://github.com/NuGet/Home/issues/1946#issuecomment-186005540 – Omar Jun 18 '16 at 23:43
  • Can confirm that using $version$ seems to work. Nice find. – Jansky Dec 05 '17 at 16:47
  • I also had issues getting $version$ working. I was able to get it working by doing this: https://stackoverflow.com/a/48384248/279516 – Bob Horn Jan 22 '18 at 14:52
22

With a .csproj for Visual Studio 2017, you don't need a .nuspec file. You can actually add the values directly to your csproj and it will pick them up.

Right click the project in Visual Studio, Edit xxxxx.csproj. Notepad works fine too.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <Version>1.0.1</Version>
    <authors>Subtracts</authors>
    <TargetFrameworks>netstandard1.6;net452</TargetFrameworks>
    <AssemblyName>Checkout.net</AssemblyName>
    <PackageId>Checkout.net</PackageId>

...

</Project>

p.s. Since I don't have sufficient reputation to comment, I am leaving an answer instead of a comment on Xavier's answer. :)

truepudding
  • 330
  • 2
  • 4
  • 1
    When you want to edit the `.csproj` file from Visual Studio you need to select _Unload Project_ before the _Edit csproj_ option becomes available. – Chrono Apr 07 '17 at 08:09
  • 4
    @Chrono That depends on the project type, it's not necessary for .NET Core and .NET Standard projects. – user247702 Aug 08 '17 at 15:39
  • 7
    @Chrono @Stijn It's not necessary when you are using the new csproj format (i.e. starts with ``). You can use the new csproj format with .net framework projects, including WPF and WinForms projects. – cube45 Nov 20 '17 at 09:46
19

For simple packages you can directly create the packages off .csproj or .vbproj. But for more advance packages, especially when you need to pull in custom files into your package, you need to use .nuspec. I usually start off with the csproj and move to nuspec as needed. You can always get the nuspec using the command nuget spec on the csproj.

https://docs.nuget.org/create/creating-and-publishing-a-package

You can specify any of the properties including licenseUrl using the Properties parameter to nuget pack

nuget pack -properties licenseUrl=http://blah
a-h
  • 4,244
  • 2
  • 23
  • 29
manojlds
  • 290,304
  • 63
  • 469
  • 417
12

With .NET Core as of February 2018 you'll need to supply a .nuspec file for any more than the basic spec file properties.

But the dotnet pack command will not use the .nuspec file unless you add <NuspecFile>relative path to nuspec</NuspecFile> to the .csproj file.

See https://github.com/dotnet/cli/issues/2170

Most packages can now be made without a .nuspec file. The thing to watch is the dependencies. You may need to add a PrivateAssets element to some that are tools, like msbump and um, SpecFlow maybe.

<PackageReference Include="msbump" Version="2.3.2">
  <PrivateAssets>all</PrivateAssets>
</PackageReference>

This stops this package dependency "flowing" to the dependencies of your package.

Also worth reading about specifying versions in the most flexible way.

https://learn.microsoft.com/en-us/nuget/consume-packages/dependency-resolution#floating-versions

And range syntax.

https://learn.microsoft.com/en-us/nuget/reference/package-versioning#references-in-project-files-packagereference

Luke Puplett
  • 42,091
  • 47
  • 181
  • 266