Azure Pipelines Nuget 还原失败 MSB4226
Posted
技术标签:
【中文标题】Azure Pipelines Nuget 还原失败 MSB4226【英文标题】:Azure Pipelines Nuget Restore Failing MSB4226 【发布时间】:2022-01-18 00:43:20 【问题描述】:我正在尝试为项目设置 Azure 管道,但我的 yml 中的 nuget restore 命令失败。以下是完整的错误:
[错误] nuget 命令失败,退出代码(1) 和错误(D:\a\1\s\UDesign\Backup\UDesign\UDesign.csproj(190,11): 错误 MSB4226: 导入的项目"找不到 C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets。另外,试图找到“Microsoft\VisualStudio\v10 .0\WebApplications\Microsoft.WebApplication.targets" 在 $(MSBuildExtensionsPath32) 的后备搜索路径中 - "C:\Program Files (x86)\MSBuild" 。这些搜索路径在 "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\msbuild.exe.Config"。确认声明中的路径是正确的,并且该文件存在于磁盘上的任一搜索路径中。) ##[error]包恢复失败
几乎所有关于此错误的帖子都在 YML 中的 Build 命令上,但在 Nuget Restore 上却失败了:
Pipelines failure image
YML 下面:
# .NET Desktop
# Build and run tests for .NET Desktop or Windows classic desktop solutions.
# Add steps that publish symbols, save build artifacts, and more:
# https://docs.microsoft.com/azure/devops/pipelines/apps/windows/dot-net
trigger:
- master
pool:
vmImage: 'windows-latest'
variables:
solution: '**/*.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
steps:
- task: NuGetToolInstaller@1
- task: NuGetCommand@2
inputs:
command: 'restore'
restoreSolution: '$(solution)'
feedsToUse: 'select'
vstsFeed: 'MyFeed'
- task: VSBuild@1
inputs:
solution: '$(solution)'
msbuildArgs: '/p:OutputPath="$(Build.BinariesDirectory)\$(Build.BuildID)"'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
restoreNugetPackages: true
msbuildArchitecture: 'x64'
- task: ArchiveFiles@2
inputs:
rootFolderOrFile: '$(Build.BinariesDirectory)\$(Build.BuildId)'
includeRootFolder: false
archiveType: 'zip'
archiveFile: '$(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip'
replaceExistingArchive: true
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'drop'
publishLocation: 'Container'
我不确定问题出在配置上还是我的 NuGet 包上,我在这个问题上找不到太多信息。
【问题讨论】:
UDesign.csproj 是解决方案的一部分吗? 不,它不是它的一部分 解决方案的根目录中有nuget.config
吗?
不,我正在使用工件提要,并且根据日志,它看起来可以正确找到包。
【参考方案1】:
实际问题
这个问题实际上与 NuGet 无关,只是 NuGet 是管道中尝试评估 MSBuild 文件的第一件事。如果你仔细看错误:
错误 MSB4226:找不到导入的项目“C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets”。
可以看到报错是MSBuild找不到Microsoft.WebApplication.targets
。这是什么意思?我不是 100% 有信心,但我非常有信心,这意味着您使用的是“自托管”CI 代理,而不是 a Microsoft hosted agent,并且任何设置机器的人都安装了 Visual Studio 2019 而没有安装 ASP.NET工作量。因此,任何设置 CI 代理的人都应该安装“ASP.NET 和 Web 开发”工作负载。
建议 1:CI 代理应使用 BuildTools SKU
如果您查看VS's release and build history,您会看到每个版本的“安装程序链接”下都有一个“BuildTools”链接。这是 Visual Studio 的一个子集,没有所有的 GUI 东西,专门用于 CI 代理。我认为 BuildTools SKU 没有工作负载选项,它只是安装所有工作负载所需的所有构建工具。
只有在极少数情况下,CI 代理才需要“完整”的 Visual Studio,因此除非您知道自己处于这种情况,否则我建议您在 CI 代理上安装 BuildTools,而不是在 Enterprise 或 Professional 上安装。
建议2:不要使用NuGetCommand
有两个原因。首先,NuGetCommand
是一个使用 NuGet.exe 的任务。 NuGet.exe 的问题在于,当您使用PackageReference
而不是packages.config
时,有时NuGet 和构建工具(msbuild 的道具/目标)会更改临时文件的文件格式。如果您没有使 NuGet.exe 的版本与 MSBuild/Visual Studio 的版本保持一致,则可能会出现构建错误。所以,最好使用dotnet restore
,或者如果你不能使用dotnet cli,那么使用msbuild -t:restore
。这样,您始终可以使用专为安装的 dotnet/msbuild 版本设计的 NuGet 的确切版本,并且您再也不必考虑 NuGet-MSBuild 版本问题。
其次,someone from the Azure DevOps team told my team that they want to deprecate these "heavy" tasks, and suggest customers call commands directly in a script task。特别是,他们实现这些功能的方式将破坏 NuGet 的新包源映射功能。
如果你的解决方案只包含 SDK 风格的项目,那么我建议你使用:
- task: NuGetAuthenticate
displayName: Set up NuGet authentication
- script: dotnet restore $(solution)
displayName: Restore
如果您的解决方案包含任何“遗留”(非 SDK 样式)项目,则不要使用 dotnet CLI,而是使用 - script: msbuild -t:restore $(solution)
。
建议 3:不要使用 VSBuild
您正在使用任务VSBuild
来运行您的构建。这是一个使用devenv.com
构建项目的任务。虽然 devenv 确实具有从命令行构建的命令行参数,但 msbuild.exe
是进行命令行构建的“官方”工具。同样,除非您知道自己处于真正需要通过devenv /build
构建的特殊情况,否则我建议您改用dotnet
CLI 或MSBuild
。如前所述,Azure DevOps 团队显然希望弃用“繁重”任务,因此我建议您使用脚本并直接调用dotnet
或msbuild
。
- script: msbuild -t:build $(solution)
displayName: Build solution
【讨论】:
这是 Azure 中有效的 Yml?这似乎不符合可以为我的管道设置的任务。例如,根据构建器的说法,您链接的任务似乎都不是有效的 yml? Fwiw 切换到 DotNetCoreCLI 并运行恢复似乎有所帮助,但这对我来说没有多大意义,因为我们没有使用核心。此外,它在 MSBuild 上失败并且无法从还原中找到任何 nuget 包,所以我不确定这是正确的解决方案。 恢复:-任务:DotNetCoreCLI@2 输入:命令:'恢复'项目:'*/.sln' feedsToUse:'select' vstsFeed:'Feed' noCache:真正的 MSBuild:-任务:MSBuild@1 输入:解决方案:'**/MyProject.sln' 作为后续,我们正在使用已发布的 yaml 中指定的 windows 托管代理:windows-latest,not self hosting 这是一个 sn-p 而不是一个完整的 yaml 文件,但是是的,它是有效的。 Here's the docs for thescript
keyword,假设您认为这是无效的。否则我不确定你认为什么是无效的。
如果任何项目使用packages.config,那么as per nuget's docs, you need to use msbuild -t:restore -p:RestorePackagesConfig=true
。否则,我没有足够的信息来帮助理解为什么构建会因缺少包而失败。这是我个人不喜欢 Azure DevOps 的 NuGetCommand 和 MSBuild 任务的原因之一,因为像传递你想要的参数这样简单的事情更难。我更喜欢自己运行命令行。【参考方案2】:
你可以试试这个
注意:你需要根据你的项目替换源路径和目标路径。
variables:
- name: BuildParameters.RestoreBuildProjects
value: '**/*.csproj'
- name: BuildParameters.TestProjects
value: '**/*[Tt]ests/*.csproj'
trigger:
branches:
include:
- refs/heads/master
name: $(date:yyyyMMdd)$(rev:.r)
jobs:
- job: Job_1
displayName: Agent job 1
pool:
vmImage: windows-2019
steps:
- checkout: self
- task: DotNetCoreCLI@2
displayName: Restore
inputs:
command: restore
projects: $(BuildParameters.RestoreBuildProjects)
- task: DotNetCoreCLI@2
displayName: Build
inputs:
projects: $(BuildParameters.RestoreBuildProjects)
arguments: --configuration $(BuildConfiguration)
- task: DotNetCoreCLI@2
displayName: Test
enabled: False
inputs:
command: test
projects: $(BuildParameters.TestProjects)
arguments: --configuration $(BuildConfiguration)
- task: DotNetCoreCLI@2
displayName: Publish
inputs:
command: publish
publishWebProjects: True
projects: $(BuildParameters.RestoreBuildProjects)
arguments: --configuration $(BuildConfiguration) --output $(build.artifactstagingdirectory)
zipAfterPublish: True
- task: PublishBuildArtifacts@1
displayName: Publish Artifact
condition: succeededOrFailed()
inputs:
PathtoPublish: $(build.artifactstagingdirectory)
TargetPath: '\\my\share\$(Build.DefinitionName)\$(Build.BuildNumber)'
...
【讨论】:
从事 Azure DevOps 工作的人似乎是 suggesting to not usetask: DotnetCoreCLI
, and instead to just use a script task and run the dotnet CLI directly。
无论哪种方式,它也会失败,但出现错误:' Build FAILED。 “D:\a\1\s\Configurator\Configurator.csproj”(恢复目标)(1) -> D:\a\1\s\Configurator\Configurator.csproj(1,1):错误MSB4075:项目文件“D:\a\1\s\Configurator\Configurator.csproj”必须在 Visual Studio IDE 中打开并转换为最新版本,然后才能由 MSBuild 构建。 0 警告 1 错误 已用时间 00:00:00.07 ##[error]Error: The process 'C:\Program Files\dotnet\dotnet.exe' failed with exit code 1 ##[error]Packages无法恢复'以上是关于Azure Pipelines Nuget 还原失败 MSB4226的主要内容,如果未能解决你的问题,请参考以下文章
Azure 构建管道 NuGet 还原错误 NETSDK1045
Azure Devops 私有构建代理在 nuget 还原任务中失败
使用 docker 将代码覆盖率结果添加到 Azure Pipelines for .NET6 Web API
我可以通过 CLI 验证 azure-pipelines.yml 文件吗?