Publish to VSTS NuGet feed from CakeBuild

I’m on a roll today – second post in the day!

Some time last year I’ve blogged about pushing a NuGet package to VSTS package feed from Cake script. Turns out there is an easier way to do it that does not involve using your own personal access token and storing it in nuget.config file.

Turns out that VSTS exposes OAuth Token to build scripts. You just need to make it available to the scripts:

In you build definition go to Options and tick checkbox “Allow Sctips To Access OAuth Token”:

Then instead of creating a nuget.config in your repository you need to create a new NuGet source on the build agent machine that has this token as a password. And then you can push packages to that feed just by using name of the new feed. Luckily Cake already has all the commands you need to do that:

Task("Publish-Nuget")
    .IsDependentOn("Package")
    .WithCriteria(() => Context.TFBuild().IsRunningOnVSTS)
    .Does(() => 
    {
        var package = ".\path\to\package.nupkg";

        // get the access token
        var accessToken = EnvironmentVariable("SYSTEM_ACCESSTOKEN");;

        // add the NuGet source into the build agent sources list
        NuGetAddSource("MyFeedName", "https://mycompany.pkgs.visualstudio.com/_packaging/myfeed/nuget/v2", new NuGetSourcesSettings()
            {
                UserName = "MyUsername",
                Password = accessToken,
            });

        // Push the package.
        NuGetPush(package, new NuGetPushSettings 
            { 
                Source ="MyFeedName",
                ApiKey = "VSTS", 
                Verbosity = NuGetVerbosity.Detailed,
            });
    });

I like this a lot better than having to faf-about with personal access token and nuget.config file. Probably the same way you can restore nuget packages from private sources – have not tried it yet.

Nuget Version

If you have noticed I specify url for the feed in format of version 2 – i.e. ending v2. This is because default nuget.exe version provided by VSTS does not yet support v3. Yet packages can take v3. Right now if you try to push to url with “v3” in it you will get error:

System.InvalidOperationException: Failed to process request. 'Method Not Allowed'. 
The remote server returned an error: (405) Method Not Allowed.. ---> System.Net.WebException: The remote server returned an error: (405) Method Not Allowed.

So downgrade the url to v2 – as I’ve done int the example above. Most of the time v2 works just fine for pushing packages. But if you really need v3 you can check-in your own copy of nuget.exe and then specify where to find this file like this:

NuGetPush(package, new NuGetPushSettings 
    { 
        Source ="AMVSoftware",
        ApiKey = "VSTS", 
        Verbosity = NuGetVerbosity.Detailed,
        ToolPath = "./lib/nuget.exe",                   
    });