MyGet Blog

Package management made easier!

NAVIGATION - SEARCH

MyGet supports Chocolatey

Chocolatey is something you need if you've ever installed, upgraded, or removed software on Windows. It is an existing, proven, almost 4 year old project. For those familiar with *nix package managers, it is a binary package manager, sort of like yum or apt-get, but for Windows. 

Here's how the team describes the tool on their Kickstarter campaign:

Chocolatey is a tool that automates all the mundane getting and installing software work for you. You just select what you want installed and within a few minutes, Chocolatey has downloaded and installed (or upgraded) that software without need for further input from you. So while Chocolatey does the hard work, you can go get some coffee. Or sleep. Or do other more important things. 

You probably start to see why we like Chocolatey!

Chocolatey has been part of the NuGet ecosystem since forever, and we are happy Chocolatey users ourselves. From the very first beta of MyGet's package sources functionality, we have had built-in support for ChocolateyIn fact: if you're using MyGet Build Services, then you are already using Chocolatey! That's right: all the tools mentioned in our Build Services docs are provisioned on our build agents using Chocolatey!

We also know some of our users are using MyGet to host their own Chocolatey repository, which in turn is just another NuGet feed. It just serves Chocolatey packages instead.

It goes without saying that we are huge fans of the Chocolatey project and we really want to encourage and support the Chocolatey team to take the project to the next level. If you're like us and love Chocolatey, we'd like to invite you to join us in backing the Chocolatey Kickstarter project! MyGet has pledged $750 to help move the project from experiment to experience.


Chocolatey has proven to be a huge time saver and invaluable tool for us, and if you feel the same, the least you can do is to get yourself a nice box of chocolates ;-)

Let's get Chocolatey!

Implementing custom package retention using webhooks

Earlier this week, we got the question if custom retention policies could be enforced on MyGet. More specific, the request was to be able to keep the latest 5 versions of a minor version (e.g. keep 1.0.6 through 1.0.2, but delete 1.0.1 and 1.0.0). We’ve introduced webhooks on MyGet to enable exactly this sort of scenarios!

Our own retention policies run whenever a package is added to a feed, so let’s see if we can implement a webhook handler that does exactly what was asked… The code for this blog post can be found in our GitHub organization.

Building the webhook handler

We’ll first need something that can run our custom logic whenever a webhook event is raised. This can be an ASP.NET MVC, Web API, NancyFx or even a PHP application. In this case, let’s go with an ASP.NET Web API controller. We want to be triggered on POST when a package added event is raised.

// POST /api/retention public async Task<HttpResponseMessage> Post([FromBody]WebHookEvent payload) { // The logic in this method will do the following: // 1) Find all packages with the same identifier as the package that was added to the originating feed // 2) Enforce the following policy: only the 5 latest (stable) packages matching the same minor version may remain on the feed. Others should be removed. string feedUrl = payload.Payload.FeedUrl; // Note: the following modifies NuGet's client so that we authenticate every request using the API key. // If credentials (e.g. username/password) are preferred, set the NuGet.HttpClient.DefaultCredentialProvider instead. PackageRepositoryFactory.Default.HttpClientFactory = uri => { var client = new NuGet.HttpClient(uri); client.SendingRequest += (sender, args) => { args.Request.Headers.Add("X-NuGet-ApiKey", ConfigurationManager.AppSettings["Retention:NuGetFeedApiKey"]); }; return client; }; // Prepare HttpClient (non-NuGet) var httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Add("X-NuGet-ApiKey", ConfigurationManager.AppSettings["Retention:NuGetFeedApiKey"]); // Fetch packages and group them (note: only doing this for stable packages, ignoring prerelease) var packageRepository = PackageRepositoryFactory.Default.CreateRepository(feedUrl); var packages = packageRepository.GetPackages().Where(p => p.Id == payload.Payload.PackageIdentifier).ToList(); foreach (var packageGroup in packages.Where(p => p.IsReleaseVersion()) .GroupBy(p => p.Version.Version.Major + "." + p.Version.Version.Minor)) { foreach (var package in packageGroup.OrderByDescending(p => p.Version).Skip(5)) { await httpClient.DeleteAsync(string.Format("{0}api/v2/package/{1}/{2}?hardDelete=true", feedUrl, package.Id, package.Version)); } } return new HttpResponseMessage(HttpStatusCode.OK) { ReasonPhrase = "Custom retention policy applied." }; }

Once we have this in place and are hosting it somewhere, we can configure the webhook on our MyGet feed.

Configuring the webhook

On our MyGet feed, we can create a new webhook. It should send application/json for the package added event to the URL where we deployed the above code.

Configure web hook

When this hook now triggers, we will be retaining just the 5 latest minor versions of a package (ignoring prereleases).

That’s it. Using nothing but webhooks, we can run our own retention policies (or other logic) when something happens on our feed (like strong-name signing packages, for example). There are a number of events that we can subscribe to!

Happy packaging!

User-defined environment variables in MyGet builds

Sometimes you may want to pass in a value to the build scripts without hard-coding it into the build script. MyGet now supports setting additional environment variables (that can be used in custom build scripts as well as plain MSBuild). From the Build Source configuration, you can add up to 15 environment variables that will be made available during build.

Edit environment variables

The open/closed eye icon next to the environment variable can be used to show/hide the environment variable value in the build log. Sometimes it is not desirable to have things like passwords or API keys shown in the build log, and by making the environment variable hidden we’ll hide it in the build log.

Shown in build log

Happy packaging!

MyGet feeds now support Target Framework Filtering

On October 1st, the NuGet team enabled Target Framework Filtering in NuGet.org's Search API. We're happy to announce we've just flipped the switch in our back-end to enable this on MyGet feeds as well! Ever since version 2.1, the NuGet clients have been sending the consuming project's target framework in the search requests. Everyone who's using NuGet 2.1 or above is going to benefit from this server-side optimization.

What does this mean for you as a package consumer?

Since NuGet will now be filtering package search results by target framework, in a nutshell, you should no longer see this dialog when installing packages:

More details about this feature can be found on the NuGet blog.

I'm using upstream package sources. Does anything change?

Yes and no. Upstream package sources that support target framework filtering, like NuGet.org and MyGet.org, may return different (but better) results from what was returned previously. For other package sources, we will return search results the way we did before.

If the clients were sending this information to the server since v2.1, what took you so long?

We want MyGet feeds to be fully compatible with the NuGet API that lives at www.nuget.org. This means we want MyGet to provide a consistent behavior from a user/client perspective.

Happy packaging!