Click here to Skip to main content
15,868,016 members
Articles / DevOps / TFS
Tip/Trick

Automated Creation of NuGet Packages

Rate me:
Please Sign up or sign in to vote.
5.00/5 (6 votes)
6 Aug 2014LGPL35 min read 55.8K   24   10
Fast, stable and powerful creation of NuGet packages

Introduction

This tip will present a simple, fast, automated and full-featured open-source solution for creation of NuGet packages.

Background

There are many methods for creation of NuGet packages such as:

  • Manually creating a NuSpec XML file, then creating a NuPkg file using NuGet.exe
  • Using NuGet Package Explorer
  • Installing an add-on to Visual Studio
  • Using a custom TFS template

My objectives in creating NuGet packages were:

  1. Create packages automatically during TFS builds
  2. Create packages automatically during local builds
  3. Fast creation of packages, so local builds won't take long
  4. Sync package version number with assembly version numbers
  5. Enable automatic assign of pre-release version number to packages
  6. Enable packaging of multiple assemblies from solution
  7. Enable automatic listing of external (NuGet package) dependencies
  8. Support dependencies on internal NuGet packages, built in same solution (during same build)
  9. Enable including source code within packages for easier step into source
  10. Automatically refresh list of source code files during each build
  11. Do not crash

However, none of the existing options met these objectives.

Using the Code

  1. Create a source for the version numbers:
    Add a shared file named VersionInfo.cs (or any other name) to your solution with the following attributes in it:
    1. AssemblyCompany, under which put your company name or the author's name
    2. AssemblyTrademark, under which put the project's URL (make sure the license is under that URL too).
    3. AssemblyFileVersion, under which put the version number for the assemblies and the NuGet packages e.g. 1.2.3.0. Leave the forth number as 0, as it will be ignored.
    4. AssemblyInformationalVersion, under which put the above version number + -sometext if the package is a pre-release package e.g. 1.2.3-alpha of 1.2.3-pre-release e.g.
    C#
    using System.Reflection;
    
    [assembly: AssemblyCompany("Your company name")]
    [assembly: AssemblyTrademark("https://your.project.url/")]
    
    [assembly: AssemblyFileVersion("1.2.3.0")]
    
    #if DEBUG
        [assembly: AssemblyInformationalVersion("1.2.3-alpha")]
    #else
        [assembly: AssemblyInformationalVersion("1.2.3")]
    #endif
  2. Synchronize version number between projects:
    Alt+Drag the VersionInfo.cs file to all the assemblies in your solution which you want to include in packages. (Alt+Drag creates a link to the file, instead of copying it the new location.)
  3. Remove the AssemblyCompany, AssemblyTrademark, AssemblyFileVersion and AssemblyInformationalVersion attributes from the AssemblyInfo.cs files to prevent duplicate attributes (which will fail build).
  4. Add a new project for your NuGet package to the solution using the standard add "Class Library" dialog (yes the standard class library template!). Called YourNuGetPackageName.NuGet (the .NuGet is optional).
  5. Repeat steps 2+3 for the new project (add link to VersionInfo.cs, remove duplicates from AssemblyInfo.cs).
  6. Add references from the new NuGet project to any assemblies within the same solution which you want included in the package.
  7. Add NuGet packages to the new NuGet project for any external NuGet packages that this package should depend on.
  8. Internal NuGet dependencies: If your package depends on other NuGet packages that are created within the same solution:
    1. Add a text file named internalPackages.config to the new NuGet project (you can copy the packages.config and rename it).
    2. Edit the internalPackages.config file so its structure will be the same as the packages.config file, however, list the NuGet packages created with the solution, e.g.
    XML
    <?xml version="1.0" encoding="utf-8"?>
    <packages>
      <package id="PubComp.NoSql.Core" version="2.0.0" targetFramework="net45" />
    </packages>
  9. List any tags you want your package to have in the attribute AssemblyTitle within AssemblyInfo.cs.
  10. Add a description for you package in the attribute AssemblyDescription within AssemblyInfo.cs.
  11. Set the package's name in the attribute AssemblyProduct within AssemblyInfo.cs.
    C#
    [assembly: AssemblyTitle("NoSQL, Repository, 
    Abstraction, Design Patterns, MongoDb")]
    [assembly: AssemblyDescription
    ("A MongoDb-based implementation of the NoSQL abstraction layer")]
    [assembly: AssemblyConfiguration("")]
    [assembly: AssemblyProduct("PubComp.NoSql.MongoDb")]
    [assembly: AssemblyCopyright("Copyright © 2014")]
    [assembly: AssemblyCulture("")]
  12. Add NuGet.exe and NuGetPack.exe to your solution's folder + add the solution itself (so they will be available to TFS builds).
    1. NuGet.exe is the standard NuGet.exe file you already have
    2. NuGetPack.exe is available as both source and binary at https://pubcomp.codeplex.com/
  13. Optional: Alternatively you can set the tags, description, summary, authors, owners, copyright, icon URL, project URL and package generation options by adding a file named NuGetPack.config to your Package Project:
    XML
    <NuGetPack>
     <AddFrameworkReferences>true</AddFrameworkReferences>
     <DoIncludeSources>true</DoIncludeSources>
     <IconUrl>http://www.nuget.org/favicon.ico</IconUrl>
     <ProjectUrl>https://pubcomp.codeplex.com/</ProjectUrl>
     <LicenseUrl>https://pubcomp.codeplex.com/license</LicenseUrl>
     <Authors>Demo Author</Authors>
     <Owners>Demo Owner</Owners>
     <Copyright>Demo Copyright</Copyright>
     <Description>Demo Description</Description>
     <Summary>Demo Summary</Summary>
     <Keywords>Demo, Key, Word</Keywords>
    </NuGetPack>
  14. If you use the "add framework references" option, then remove any framework references that are not really required from the package project.
  15. Optional: You can include content under a folder named content in the package project.
    The content files can be added as links instead of copies of the originals if you drag them with the ALT key pressed down or if you use the drop down option of "Add As Link" on the "Add" button when using the "Add Existing Item" menu option.
  16. Optional: You can include (non-NuGet) binaries under a folder named lib in the package project. To include .NET Framework version specific binaries, place them under sub folders e.g. lib\net20, lib\net40 and etc.
    As in the content files, these files may be added as links or copies of the original files.
  17. Optional: You can include items that are to remain under the packages folder, yet not added to any projects by adding them under a folder named sln in the package project.
    As in the content files, these files may be added as links or copies of the original files.
  18. The .NET Framework version your package depends on is set by the Framework version of the package project. To change it, change the "Target Framework" of the package project via the project's Properties.
  19. Add the following post-build event to your NuGet project:
    C#
    "$(SolutionDir)NuGetPack.exe" "$(ProjectPath)" "$(TargetPath)" $(ConfigurationName)
  20. Repeat steps 4-19 for each additional NuGet package you want to create.
  21. Build your solution.
  22. The NuPkg (and NuSpec) files will be under the output folder (e.g. bin\Debug, bin\Release).

Update

NuGetPack.exe is now available as a NuGet and a Project Template for NuGet packages is now available as a VSIX.

Points of Interest

Next time, I'll show you how to automatically pull NuGet package dependencies from custom sources and push output NuGet packages to any source during TFS builds.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)


Written By
Architect
Israel Israel
A Software Developer with over 12 years of experience in Software Analysis, Design and Development, Domain Modelling, Requirement Analysis, Product Management, Leading Development, Mentoring, System Analysis and Design and in Innovating.

Experienced in a variety of domains and in Interdisciplinary Development too.

Specializes in analysing existing environments, identifying points for improvement and new opportunities and coming up with innovative solutions.

Graduated with awards in Computer & Software Engineering. (Technion - Israel Institute of Technology)

Comments and Discussions

 
QuestionNext time? Pin
vercellone21-Jan-15 14:26
vercellone21-Jan-15 14:26 
AnswerRe: Next time? Pin
DannyVarod8-Oct-15 12:10
DannyVarod8-Oct-15 12:10 
Hi,
Sorry for the late reply, I haven't been getting notifications from here.
I have the pull solution ready using custom MS-Build proj file, however, I didn't implement the push yet. Perhaps if you tell me a bit more about your use cases, I'll be able to suggest something. Do you mind posting this and any future requests in the project's site (CodePlex), so it'll be easier for me to monitor.
Regards,
Danny.
QuestionError on Include Build folder Pin
gclpixel19-Dec-14 0:26
gclpixel19-Dec-14 0:26 
AnswerRe: Error on Include Build folder Pin
DannyVarod8-Oct-15 11:19
DannyVarod8-Oct-15 11:19 
QuestionHow to include Content. Pin
tangr11-Sep-14 5:17
tangr11-Sep-14 5:17 
AnswerRe: How to include Content. Pin
DannyVarod11-Sep-14 21:45
DannyVarod11-Sep-14 21:45 
GeneralRe: How to include Content. Pin
tangr12-Sep-14 9:48
tangr12-Sep-14 9:48 
GeneralRe: How to include Content. Pin
tangr12-Sep-14 16:28
tangr12-Sep-14 16:28 
GeneralRe: How to include Content. Pin
DannyVarod13-Sep-14 6:19
DannyVarod13-Sep-14 6:19 
GeneralRe: How to include Content. Pin
DannyVarod15-Sep-14 9:18
DannyVarod15-Sep-14 9:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.