NuGet 恢复 - 如何让它将警告视为错误?

NuGet restore - how to make it treat warnings as errors?

由于缺少.NET Core SDK,包恢复仅部分成功并省略了SDK项目。

WARNING: Error reading msbuild project information, ensure that your input solution or project file is valid. NETCore and UAP projects will be skipped, only packages.config files will be restored.

这只是一个警告,nuget.exe 以状态码 0 退出,因此构建管道会继续并稍后失败,从而更难找到原因。

因为这是我们环境中的常见问题,所以我希望将此警告视为错误。如果其他警告也被视为错误,那是完全可以的(甚至是可取的)。

我知道NuGet reads MSBuild properties TreatWarningsAsErrors and WarningsAsErrors, but I have not managed to use them from command line. I tried setting NUGET_RESTORE_MSBUILD_ARGS environment variable to /p:TreatWarningsAsErrors=true, but even though the option was passed to the internal MSBuild call, it did not affect the warning printed by nuget.exe. I did not find any other suitable CLI options nor environment variables

上下文

在本地 Azure Pipelines 构建中,我 运行 一个 NuGet 任务来恢复我的解决方案的包。该解决方案包含以 .NET Framework 为目标并使用 packages.config 的项目以及以 .NET Core 为目标使用 PackageReference 的项目。

构建代理不在我的控制之下。有些安装了正确的 SDK 版本,有些则没有。我使用 .NET Core SDK Installer 任务来安装相应的 SDK。

由于构建定义的更改或解决方案中的 SDK 更新,构建可能会中断。但是,在那种情况下,错误消息是模糊的,因为它来自 VS 构建,而不是来自包还原构建步骤,根本原因在于此,但它是绿色的。

在内部,NuGet 任务(版本 2.*)执行 nuget.exe(当前版本 5.0.2),后者又执行 MSBuild 以执行与 PackageReference 相关的部分工作。 MSBuild 失败,导致 NuGet.CommandLine.ExitCodeException 被抛出,但被捕获、记录并丢弃。就在上面提到的 Warning_ReadingProjectsFailed 警告之上,打印了堆栈跟踪:

NuGet.CommandLine.ExitCodeException: Exception of type 'NuGet.CommandLine.ExitCodeException' was thrown.
    at NuGet.CommandLine.MsBuildUtility.<GetProjectReferencesAsync>d__6.MoveNext()
 --- End of stack trace from previous location where exception was thrown ---
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
    at NuGet.CommandLine.RestoreCommand.<GetDependencyGraphSpecAsync>d__52.MoveNext()
 --- End of stack trace from previous location where exception was thrown ---
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
    at NuGet.CommandLine.RestoreCommand.<DetermineInputsFromMSBuildAsync>d__47.MoveNext()

catch 子句顶部的注释说:

                // At this point reading the project has failed, to keep backwards
                // compatibility this should warn instead of error if
                // packages.config files exist, but no project.json files.
                // This will skip NETCore projects which is a problem, but there is
                // not a good way to know if they exist, or if this is an old type of
                // project that the targets file cannot handle.

NuGet restore - how to make it treat warnings as errors?

恐怕我们目前无法让它将警告视为错误,因为这种行为是设计的

我已经向 NuGet 团队报告 a similar issue 并且收到了以下回复:

This message is expected, but it should not block your restore.

In the future once msbuild provides a way to skip projects that are missing a target this message will go away: microsoft/msbuild#2471

此外,属性 TreatWarningsAsErrors 在项目范围级别为 one/all NuGet 警告设置,但当 MSBuild/VS 开始读取项目文件时将抛出上述警告.csproj。这就是 属性 TreatWarningsAsErrors 无法正常工作的原因,即使它已设置。

由于构建代理不在您的控制之下,我们无法直接在代理上安装所需的.NET Core SDK 版本,向代理添加相应的功能,并在构建管道中添加对该功能的需求.看来我们必须在microsoft/msbuild#2471下添加评论,询问我们是否可以使用扳手来设置信息是错误还是警告。