使用混合 .NET Core 和框架解决方案的 Azure Devops 中的 Cake 构建脚本失败

Cake build script fails in Azure Devops with mixed .NET Core and framework solution

我有一个 Cake 构建脚本,我的 .NET 服务器项目需要构建在我们新的 Azure DevOps pipeline. The script works locally, but does not work on Azure DevOps. There are possible reasons for this which may be that I have a unit tests project (xUnit) 上,构建在 .NET Core 2.1 上,而解决方案中的所有其他项目都是 .NET Framework 4.6。 1(我们刚刚添加到 xUnit 项目中,我唯一的选择是将其作为 .NET Core 项目添加)。

我编写了可在本地运行的 Cake 脚本。它看起来像这样:

// Always lock down versions of tools so that we can ensure
// a tool works before upgrading instead of auto-upgrading.
#tool "nuget:?package=xunit.runner.console&version=2.4.1"
#tool "nuget:?package=ReportUnit&version=1.2.1"

var target = Argument("target", "Build");
var configuration = Argument("configuration", "Dev");
var solution = @".\MyCompany.MyProduct.IntegrationLayer.sln";
var report = Directory(@".\reports");
var xunitReport = report + Directory("xunit");

Task("Clean")
    .Does(() =>
{
    Information("Cleaning out directories {0} for {1}...", configuration, solution);
        CleanDirectories("./**/bin/" + configuration);
        CleanDirectories("./**/obj/" + configuration);
});

Task("Restore")
    .IsDependentOn("Clean")
    .Does(() =>
{
    // This can restore both .NET Core and Framework NuGet packages.
    Information("Restoring Nuget packages for {0}...", solution);
    DotNetCoreRestore();
});

Task("Build")
    .IsDependentOn("Restore")
    .Does(() =>
{
    // If we change all the projects and solution to .NET Core, then
    // we will need to change this build call to DotNetCoreBuild().
    //
    // Because we have a mixed solution (unit tests are .NET Core and all
    // other projects are .NET Framework), we need to still use MSBuild.
    Information("Building solution {0} using the {1} configuration...", solution, configuration);
    MSBuild(solution, new MSBuildSettings {
        Configuration = configuration
    });
});

Task("UnitTests")
    .IsDependentOn("Build")
    .Does(() =>
{
    Information("Unit testing solution {0} using the {1} configuration...", solution, configuration);
    var projects = GetFiles("./UnitTests/*.csproj");
    foreach(var project in projects)
    {
        DotNetCoreTest(
            project.FullPath,
            new DotNetCoreTestSettings()
            {
                Configuration = configuration,
                NoBuild = true
            });
    }
});

Task("UnitTestsOnly")
    .Does(() =>
{
    Information("Unit testing solution {0} using the {1} configuration...", solution, configuration);
    var projects = GetFiles("./UnitTests/*.csproj");
    foreach(var project in projects)
    {
        DotNetCoreTest(
            project.FullPath,
            new DotNetCoreTestSettings()
            {
                Configuration = configuration,
                NoBuild = true
            });
    }
});

RunTarget(target);

现在,当我 运行 在 Azure DevOps 中执行此操作时,每个项目都会出现 10 个错误,类似于下面的示例:

"D:\a\s\PPIL\MyCompany.MyProduct.IntegrationLayer.sln" (Build target) (1) ->
"D:\a\s\PPIL\MC.MP.IL.DatabaseDataReset\MC.MP.IL.DatabaseDataReset.csproj" (default target) (11) ->
  D:\a\s\PPIL\MC.MP.IL.DatabaseDataReset\MC.MP.IL.DatabaseDataReset.csproj(123,5): error : This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is ..\packages\Microsoft.VisualStudio.SlowCheetah.3.1.66\build\Microsoft.VisualStudio.SlowCheetah.targets.

我不确定到底是什么问题。可能是因为我们有一个混合项目。可能是因为文件结构。我不知道我需要在 Cake 命令中设置哪些选项或设置以进行构建或恢复。也可能是当我在本地 运行 时,我 运行 它在与 Cake 脚本相同的文件夹中,但它似乎在我的存储库的根文件夹中 运行ning此解决方案的解决方案文件夹上一个文件夹。

我的脚本哪里出错了?我的恢复步骤看起来很好,除了它只恢复单元测试项目(它依赖于所有其他项目)。是还原吗?构建或恢复中是否缺少我的设置?

所以答案是我得到了所有的项目文件和 运行 "NuGetRestore" 方法不包括 .NET Core 单元测试项目。然后我可以 运行 DotNetCoreRestore 方法,它只恢复 .NET Core UnitTests 项目。

我还发现我应该清理包目录,因为这是一个好习惯。

正如您在 How to restore only a specific solution folder with an MSBuild command 中看到的那样,您可以使用特定的 .proj 文件来区分这些项目并非常轻松地使用它们。

但我建议您使用以下命令毫无问题地恢复所有项目,如果您有 Visual Studio 2019:

MSBuildSettings settings = new MSBuildSettings
{
    ArgumentCustomization = args =>
        .Append("-p:RestoreUseSkipNonexistentTargets=false")
        .Append("-p:RestorePackagesConfig=true"),
    ToolPath = msBuildPath
};

MSBuild("YourSolution.sln", settings.WithTarget("restore"));

使用以上代码,您可以恢复所有项目,无论项目类型是 .NET Framework 还是 .NET Core。