Uploading Packages To The NuGet Gallery

nuget, open source 0 comments suggest edit

As David Ebbo blogged today, the NuGet Gallery is now open to the public. The goal of the NuGet Gallery is to be the hub for NuGet users and package authors alike. Users should be able to search and discover packages with detailed information on each one and eventually rate them. Package authors can register for an API key and upload packages.

We’re not quite where we want to be with the gallery, but we’re moving in the right direction. If you want to see us get there more quickly, feel free to lend a hand. The gallery is running on fully open source code!

In this blog post, I wanted to cover step by step what it takes to create and upload a package.

Create Your Package

Well the first step is to create a package so you have something to upload. If you’re well acquainted with creating packages, feel free to skip this section, but you may learn a few tips if you stick with it.

I’ll start with a simple example that I did recently. The XML-RPC.NET library by Charles Cook is very useful for implementing XML-RPC Services and clients. It powers the MetaWeblog API support in Subtext. As a courtesy, I recently asked Charles if he would mind if I created a NuGet package for his library for him, to which he said yes!

So on my machine, I created a folder named after the latest 2.5 release, xmlrpcnet.2.5.0. Here’s the directory structure I ended up with.

package-folder-structure

By convention, the lib folder is where you place assemblies that will get added as referenced assemblies to the target project when installing this package. Since this assembly only supports .NET 2.0 and above, I put it in the net20 subfolder of the lib folder.

The other required file is the .nuspec file, which contains the metadata used to build the package. Let’s take a look at the contents of that file.

<?xml version="1.0" encoding="utf-8"?> 
<package> 
  <metadata> 
    <id>xmlrpcnet</id> 
    <version>2.5.0</version> 
    <authors>Charles Cook</authors> 
    <owners>Phil Haack</owners>
    <description>A client and server XML-RPC library for .Net.</description> 
    <projectUrl>http://www.xml-rpc.net/</projectUrl>
    <licenseUrl>http://www.opensource.org/licenses/mit-license.php</licenseUrl>
    <tags>xml-rpc xml rpc .net20 .net35 .net40</tags>
    <language>en-US</language> 
  </metadata> 
</package>

There’s a couple of things I want to call out here. Notice that I specified Charles Cook in the authors element, but put my own name in the owners element. Authors represent the authors of the library within the package, while the owner typically represents the person who created the package itself. This allows people to know who to contact if there’s a problem with the package vs a problem with the library within the package.

In general, we hope that most of the time, the authors and the owners are one and the same. For example, someday I’d love to help Charles take ownership of his packages. Until that day, I’m happy to create and upload them myself.

If somebody creates a package for a library that you authored and uploads it to NuGet, assume it’s a favor they did to get your library out there. If you wish to take ownership, feel free to contact them and they can assign the packages over to you. This is the type of thing we’d like to see resolved by the community and not via some policy rules on the gallery site. This is a case where the gallery could do a lot to make this sort of interaction easier, but does not have such features in place yet.

With this in place, it’s time to create the package. To do that, we’ll need the NuGet.exe console application. Copy it to a utility directory and add it to your path, or copy it to the parent folder of the package folder.

nuget-dir

Now, open a command prompt and navigate to the directory and run the nuget pack command.

nuget pack path-to-nuspec-file

Here’s a screenshot of what I did:

nuget-pack

Pro tip: What I really did was add a batch file I call build.cmd in the same directory that I put the NuGet.exe file. The contents of the batch file is a single line:

for /r %%x in (*.nuspec) do nuget pack "%%x" -o d:\packages\

What that does is run the nuget pack command on every subdirectory of the current directory. I have a folder that contains multiple packages that I’m working on and I can easily rebuild them all with this batch file.

Ok, so now we have the package, let’s publish it! But first, we have to create an account on the NuGet Gallery website.

Register and Upload

The first step is to register for an account at http://nuget.org/Users/Account/Register. Once you have an account, click on the Contribute tab. This page gives you several options for managing packages (click to enlarge).

contribute-tab

To upload your package, click on the Add New Package link.

upload-package

Notice there’s two options. At this point, you can simply browse for the package you created and upload it and you’re done. In a matter of a few minutes, it should appear in the public feed.

The second option allows you to host your package file in a location other than the NuGet gallery such as CodePlex.com, Google Code, etc. Simply enter the the direct URL to the package and when someone tries to install your package, the NuGet client will redirect the download request to the external package URL.

Submit From The Command Line

Ok, that’s pretty easy. But you’re a command line junky, right? Or perhaps you’re automating package submission.

Well you’re in luck, it’s pretty easy to submit your package directly from the command line. But first, you’re going to need an API key.

Visit the My Account page (http://nuget.org/Contribute/MyAccount) and make a note of your API key (click image below to enlarge it).

nuget-gallery-api-key

Be sure to keep that API key secret! Don’t give it out like I just did. If you do happen to accidentally leak your API key, you can click the Generate New Key button, again like I just did. You didn’t really think I’d let you know my API key, did you?

Now, using the same NuGet.exe command line tool we downloaded earlier, we can push the package to the gallery using the nuget push command.

nuget push path-to-nupkg api-key –source http://packages.nuget.org/v1/

Here’s a screenshot of the exact command I ran.

publishing-nupkg

Shoot! There I go showing off my secret API key again! I better regenerate that.

As you can see, this command uploaded my package and published it to the feed. I can login and visit the Manage My Contributions page to see this package and even make changes to it if necessary.

Moving Forward

We’re still working out the kinks in the site and hopefully, by the time you read this blog post, this particular issue will be fixed. Also, we’re planning to update the NuGet.exe client and make the NuGet gallery be the default source so that the –source flag is not required.

As David mentioned, the site was primarily developed as a CodePlex.com project by the Nimble Pros in a very short amount of time. There’s two major components to the site. There’s the front-end Orchard Gallery built as an Orchard module. This powers the gallery website that you see when you visit http://nuget.org/. There’s also the back-end gallery server which hosts the OData feed used to browse and search for packages as well as the WCF service endpoint for publishing packages.

Each of these components are open source projects which means if you really wanted to, you could take the code and host your own gallery website. Orchard will be using the same code to host its own gallery of Orchard modules.

Also, these projects accept contributions! I personally haven’t spent much time in the code, but I hope to find some free time to chip in myself.

Found a typo or error? Suggest an edit! If accepted, your contribution is listed automatically here.

Comments

avatar

20 responses

  1. Avatar for ulu
    ulu January 11th, 2011

    You know, I really believed you gave out your secret API key.

  2. Avatar for Andrew Davey
    Andrew Davey January 11th, 2011

    I created an account, followed the emailed activation link. But whenever I log on it just returns me back to the log on page, no error message is displayed.
    Who do I need to tell about this?
    I have a package I'm keen to get online.

  3. Avatar for Khalid Abuhakmeh
    Khalid Abuhakmeh January 11th, 2011

    Wow, you aren't kidding when you say the site is still in Beta. I would even say Alpha at this point. All the links at the bottom seem to be broken, I can't login after registering, there is no confirmation when registering, and it says "Orchard Gallery" a couple of places. Otherwise it looks great.
    Anything I can do to help make the site better?

  4. Avatar for Andrey Shchekin
    Andrey Shchekin January 11th, 2011

    Great, but the license question (http://galleryserver.codeplex.com/workitem/2) is still unresolved.
    Now could you tell me whether I can use, for example, nuget.org/.../Adam-JSGenerator-1-1-0-0 in a commercial project?
    Well, I can always hunt the author of each specific package or just not care about licensing, but is it good for anyone?

  5. Avatar for Fernando Nomellini
    Fernando Nomellini January 11th, 2011

    Can you tell me what is the port that NuGet uses ? And what is the protocol ? My company's firewall is blocking my access this feature, so I can not get any package... :-(

  6. Avatar for Joel Martinez
    Joel Martinez January 11th, 2011

    you know, "haackpackages" seems redundant, you should just name your directory "haackages" ;-)

  7. Avatar for Chris Patterson
    Chris Patterson January 11th, 2011

    If the term "HaackPackage" catches on, wow, that would make for some interesting side discussions.

  8. Avatar for haacked
    haacked January 11th, 2011

    For those of you having login problems, please read David's announcement. We currently are manually approving accounts during this pre-launch phase.
    @Andrey we recommend package authors specify a license. I'm not sure if we require it. Is your suggestion that we require it? For now, you will need to hunt them down.
    @Fernando port 80. It's all HTTP.
    @Joel interesting. ;)

  9. Avatar for Andrey Shchekin
    Andrey Shchekin January 12th, 2011

    @haacked I suggest you require it. Obviously, I can hunt authors (though it is much more inconvenient for me to find ways to contact author than for author to provide a license).
    However this is step backwards from most places I got binaries before (Google Code/CodePlex/SourceForge), since in *all* of them license is mandatory.
    Also, there are ton of developers who will not do the hunt and either ignore the package out of fear for unknown licensing or just use without caring about a license (which in the case of GPL in commercial project may be a critical problem later on, if unnoticed in time).
    Final point is that if license is mandatory, it is possible to automatically prove licensing correctness for a used set of packages, which nicely solves the unnoticed GPL problem.

  10. Avatar for haacked
    haacked January 12th, 2011

    @Andrey I logged a bug against the Orchard Gallery here with your suggestion.

  11. Avatar for Andrey Shchekin
    Andrey Shchekin January 12th, 2011

    Thanks, resolving this would be great.
    It is somewhat amusing that now there are 3 issues about that:
    1. http://nuget.codeplex.com/workitem/363 (Closed/Moved)
    2. http://galleryserver.codeplex.com/workitem/2 (Open, 4 votes)
    3. http://orchardgallery.codeplex.com/workitem/164 (New one)

  12. Avatar for Doug Finke
    Doug Finke January 12th, 2011

    PowerShell Pro Tip:
    Here is the PowerShell version to run the nuget pack command on every subdirectory of the current directory.
    dir . -r *.nuspec | % { nuget pack $_.fullname -o d:\packages\ }

  13. Avatar for Adam Anderly
    Adam Anderly January 14th, 2011

    Phil,
    I get how to express NuGet dependencies on other NuGet packages and how to include assembly reference like you did above with the Xml RPC library. But how do I express dependencies on assemblies that I don't own (that may already be on the user's machine). For instance, if I wanted my NuGet package to add a reference to WebMatrix.WebData.dll, how I can express that dependency in my NuGet package without having to include that assembly in my lib folder of my NuGet package?
    Thanks in advance!

  14. Avatar for haacked
    haacked January 29th, 2011

    @Adam we don't have a clear way to do that, but we're working on it.

  15. Avatar for Shane Whittet
    Shane Whittet March 15th, 2011

    Call for submission by Oracle of a NuGet package that provides a bin deployable/web.config package. Otherwise, anyone with the correct steps to xcopy deploy this beta, please let me know!

  16. Avatar for Sergi Gisbert
    Sergi Gisbert April 28th, 2011

    Hi Phil,
    great stuff!! We are changing all our local libraries to a new Nuget repository in our intranet. This will make our lives much easier...
    I have one question for you: with the last nuget version, you can use metadata from AssemblyInfo.cs, so instead of doing "nuget pack project.nuspec", you can do "nuget pack project.csproj".
    I've seen your batch file doing:
    for /r %%x in (*.nuspec) do nuget pack "%%x" -o d:\packages\
    but I would like to do something like
    for /r %%x in (*.nuspec) do nuget pack "%%x.csproj" -o d:\packages\
    I mean, foreach .nuspec file, pack the corresponding .csproj file.
    I haven't achieved that. Instead, my batch file has one entry per project, which is not so cool and not reusable... Any ideas? I'm not really an expert with .cmd files...
    Thanks again!
    Sergi

  17. Avatar for haacked
    haacked May 3rd, 2011

    Perhaps change it to:

    for /r %%x in (*.csproj) do nuget pack "%%x" -o d:\packages\

  18. Avatar for Sergi Gisbert
    Sergi Gisbert May 3rd, 2011

    Hi Phil,
    Thanks for your reply. I cannot do that as I have some .csproj which will not become a Nuget package, so looking for all the .nuspec files is just what I need, but want to use the .csproj file as the input parameter.
    Another question would be: if the .nuspec file has those replacement tokens (%id%, ...) to get the metadata from the project, would packaging the .nuspec file instead of the .csproj file have the same effect?
    Thanks again,
    Sergi

  19. Avatar for haacked
    haacked May 4th, 2011

    Hi Sergi. I see. You want to grab all the .csproj files in a directory that also contains a .nuspec. That's beyond my CMD knowledge. Perhaps try using PowerShell. :)

  20. Avatar for Sergi Gisbert
    Sergi Gisbert May 5th, 2011

    That's it, Phil. I'll take a look with PS. Thanks anyway!