Serverless custom NuGet feeds

Serverless custom NuGet feeds

Some time ago I posted the following question on twitter:

has anyone done a serverless @nuget gallery using azure functions and blob storage? I totally need one ;)

I was basically looking for a serverless solution that would be independent of our CI so that multiple builds from various sources we have around could push nuget packages in a consistent fashion and we could access them reliably without the burden of maintaining a nuget gallery.

I’d argue the need for a full-blown website/gallery is typically unnecessary, unless you’re hosting this for end users. But for enterprises, internal dogfooding and even personal projects, all you typically need is a reliable and fast feed.

Justin Emgarten from the NuGet team at Microsoft pointed me at his super awesome Sleet project which allows you to create such feeds and host them in ASP.NET or Azure Blob Storage.

I wanted an even more streamlined experience for the serverless Azure Blob Storage-based solution, with explicit support for MSBuild. Basically I wanted to:

  • Install/restore a nuget package
  • Declare via MSBuild some .nupkg(s) to push
  • Invoke msbuild /t:push

So extending his awesome tool, I created the Sleet.Azure package, which does exactly that.

All you need to provide are the following properties:

   <!-- Azure storage access key for the connection -->
   <StorageAccessKey Condition="'$(StorageAccessKey)' == ''" />
   <!-- Azure storage account to use (aka "the sub-domain" in * or * for the CDN endpoint) -->
   <StorageAccount Condition="'$(StorageAccount)' == ''" />
   <!-- Azure storage container name where the feed will be stored (aka "the folder") -->
   <StorageContainer Condition="'$(StorageContainer)' == ''" />

Then the packages you intend to push:

   <Package Include="bin\*.nupkg" >

And finally just invoke msbuild /t:push on that project.

Combined with trivially created nuget packages in VS2017, this allows you to quickly get a private Azure Storage-based feed up and running with no code and no fuss. And it’s even automatically CDN enabled!

By default, Push will validate and automatically initialize (if empty or non-existing) the feed on every push. This is a somewhat costly and slow-ish operation. So you can alternatively set <SleetInit>false</SleetInit> (or pass in /p:SleetInit=false) and run the Init target just once before the first Push call.

You can check the source at the GitHub project which coincidentally is a nice simple example of a corebuild project that creates its nuget package using NuGetizer 3000 ;).

Happy nugeting!