Search code examples
c#azure-devopsnugetcakebuild

Can I get NugetRestore to work with build.cake on azure devops (TFS)


I am trying to extract build tasks from TFS to cake scripts so that the build tasks get versioned together with the code. I have managed to create a script which cleans, NuGet-restores, builds, and runs unit tests on my project. It all works fine locally. however, after configuring TFS to run my cake script it keeps failing on following error:

2019-07-24T11:30:58.0377820Z ##[error]Unable to find version '4.4.3' of package 'System.Data.SqlClient'.
2019-07-24T11:30:58.0385573Z ##[error]Unable to find version '11.0.1' of package 'Newtonsoft.Json'.
2019-07-24T11:30:58.0401542Z ##[error]An error occurred when executing task 'Restore-Nuget-Packages'.
2019-07-24T11:30:58.0449315Z ##[error]Error: One or more errors occurred.
2019-07-24T11:30:58.0450913Z ##[error]  NuGet: Process returned an error (exit code 1).
2019-07-24T11:30:58.0739069Z ##[error]System.Exception: Unexpected exit code 1 returned from tool Cake.exe

I tried to change the Cake task settings to use different versions of Nuget and feed urls. Currently, they look like this:

Nuget Exe Location: https://dist.nuget.org/win-x86-commandline/latest/nuget.exe

Tool Feed Url: https://api.nuget.org/v3/index.json

We do have a private nuget host and I have tried modifying the tool feed url. However, from the logs it seems like the feed urls are OK.

Cake output:

Feeds used:
2019-07-24T11:30:55.7676783Z   C:\Users\{usr}\AppData\Local\NuGet\Cache
2019-07-24T11:30:55.7677002Z   C:\Users\{usr}\.nuget\packages\
2019-07-24T11:30:55.7677066Z   http://{ournugeturl}
2019-07-24T11:30:55.7677233Z   http://{ournugeturl2}
2019-07-24T11:30:55.7677301Z   http://{ournugeturl3}
2019-07-24T11:30:55.7677572Z   C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\

Other nuget packages are installed, e.g,

2019-07-24T11:30:55.7882050Z Restoring NuGet package Autofac.4.8.1.
2019-07-24T11:30:55.9806596Z Adding package 'Autofac.4.8.1' to folder 'd:\w1\3263\s\packages'

I even set the verbosity level to Detailed in the Nuget-Restore task, however, I do not manage to find where the problem is.

Snippet from cake.build.

Task("Restore-Nuget-Packages")
    .IsDependentOn("Clean")
    .Does(() =>
    {
        NuGetRestore(solution, new NuGetRestoreSettings {
            Verbosity = NuGetVerbosity.Detailed,
        });
    });

my NuGet.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <solution>
    <add key="disableSourceControlIntegration" value="true" />
  </solution>
  <packageSources>
    <add key="privaterepo1" value="http://privatenugetrepo/nuget/NTS" />
    <add key="privaterepo2" value="http://privatenugetrepo/Default" />
    <add key="nugetv3" value="https://api.nuget.org/v3/index.json" />
  </packageSources>
  <activePackageSource>
    <add key="All" value="(Aggregate source)" />
  </activePackageSource>
  <packageRestore>
    <add key="enabled" value="True" />
  </packageRestore>
</configuration>

build.cake

#tool "nuget:?package=xunit.runner.console&version=2.4.1"

var target = Argument("target", "Default");
var configuration = Argument("configuration", "Release");

var solution = "./pathtosolution.sl";

////////////////////////////////////////////////
///// Clean the project packages
////////////////////////////////////////////////
Task("Clean")
    .Does(() => 
  {
        CleanDirectory("./packages");
    });

////////////////////////////////////////////////
///// Adds private Nuget feed links
////////////////////////////////////////////////
Task("Add-Private-NuGet-Feed")
    .Does(() =>
  {
    string[] sources = {
      "private-src1",
      "private-src2",
      "https://api.nuget.org/v3/index.json"
      };

    foreach(string feed in sources)
    {
      if (!NuGetHasSource(feed))
      {
        var accessToken = EnvironmentVariable("SYSTEM_ACCESSTOKEN")
                            ?? throw new Exception("VSTS System Access Token is required to setup Private NuGet Feed");
      Information($"Source {feed} is missing");
      NuGetAddSource($"MyCompany-NuGet {feed}", feed, new NuGetSourcesSettings
      {
        UserName = "VSTS",
        Password = accessToken,
    }
        );
      } else 
      {
        Information($"Source {feed} Exists");
      }
    }

  });

////////////////////////////////////////////////
///// Restores all nuget packages.
////////////////////////////////////////////////
Task("Restore-Nuget-Packages")
  .IsDependentOn("Add-Private-NuGet-Feed")
  .Does(() =>
  {
    var solutions = GetFiles("./**/*.sln");
    // Restore all NuGet packages.
    foreach(var solution in solutions)
    {
      Information(solution);
      Information("Restoring {0}", solution);
      var nugetRestoreSettings = new NuGetRestoreSettings {
    ConfigFile = new FilePath("./NuGet.Config"),
    //MSBuildVersion = NuGetMSBuildVersion.MSBuild15
};
      NuGetRestore(solution, nugetRestoreSettings);
    }
  });

////////////////////////////////////////////////
///// Runs DotNetCoreRestore
////////////////////////////////////////////////
Task("DotNetCoreRestore")
  .Does(() => 
  {
    DotNetCoreRestore(
      solution,
      new DotNetCoreRestoreSettings()
      {});
  });

////////////////////////////////////////////////
///// Runs unit tests.
////////////////////////////////////////////////
Task("xUnit")
  .IsDependentOn("Build")
    .Does(() =>
  {

     var projects = GetFiles("./*.Tests/**/*.Tests.csproj");
    foreach(var project in projects)
    {
      DotNetCoreTest(
      project.FullPath,
      new DotNetCoreTestSettings()
        {
        // Set configuration as passed by command line
        Configuration = configuration
        });
    }
  });

////////////////////////////////////////////////
///// Build
////////////////////////////////////////////////
Task("Build")
  .IsDependentOn("Clean")
  .IsDependentOn("Add-Private-Nuget-Feed")
  .IsDependentOn("DotNetCoreRestore")
  .IsDependentOn("Restore-Nuget-Packages")
  .Does(() =>
  {
    MSBuild(solution, new MSBuildSettings {
        ToolVersion = MSBuildToolVersion.VS2017});
  });

////////////////////////////////////////////////
///// The main task.
////////////////////////////////////////////////
Task("Default")
  .IsDependentOn("xUnit");

RunTarget(target);

Solution

  • Solved

    By replacing the Cake task in TFS with a Powershell Script invoking build.ps1 on the build server resolved my problem. TFS screenshot where CAKE is disabled and replaced with powershell script.