我正在尝试为项目设置 Azure 管道,但我的 yml 中的 nuget restore 命令失败。以下是完整的错误:
[错误]nuget 命令失败,退出代码 (1) 和错误 (D: \s\UDesign\Backup\UDesign\UDesign.csproj(190,11): error MSB4226: The imported project "C:\Program文件 (x86)\Microsoft Visual Studio�9\Enterprise\MSBuild\Microsoft\VisualStudio 10.0\WebApplications\Microsoft.WebApplication.targets" 未找到。另外,尝试查找“Microsoft\VisualStudio 10.0\WebApplications\Microsoft.WebApplication.targets " 在 $(MSBuildExtensionsPath32) - "C:\Program Files (x86)\MSBuild" 的回退搜索路径中。这些搜索路径在 "C:\Program Files (x86)\Microsoft Visual Studio�9\ Enterprise\MSBuild\Current\Bin\msbuild.exe.Config。确认声明中的路径正确,并且该文件存在于磁盘上的搜索路径之一中。) ##[错误]包恢复失败
几乎所有关于此错误的帖子都在 YML 中的构建命令上,但这在 Nuget 恢复上失败了:
下面的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://learn.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 包上,我在这个问题上找不到太多信息。
你能试试这个吗
注意: 你需要根据你的项目替换源和目标路径。
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)'
...
问题实际上与 NuGet 无关,只是 NuGet 是管道中尝试评估 MSBuild 文件的第一件事。仔细看错误的话:
错误 MSB4226:找不到导入的项目“C:\Program Files (x86)\Microsoft Visual Studio�9\Enterprise\MSBuild\Microsoft\VisualStudio 10.0\WebApplications\Microsoft.WebApplication.targets”。
可以看到报错是MSBuild找不到
Microsoft.WebApplication.targets
。这是什么意思?我不是 100% 有信心,但我非常有信心这意味着您使用的是“自托管”CI 代理,而不是 Microsoft 托管代理,并且设置机器的人安装了 Visual Studio 2019 而没有安装ASP.NET 工作负载。因此,无论谁设置您的 CI 代理,都应该安装“ASP.NET 和 Web 开发”工作负载。
如果您查看 VS 的发布和构建历史,您会看到每个版本在“安装程序链接”下都有一个“BuildTools”链接。这是 Visual Studio 的一个子集,没有所有 GUI 内容,专门用于 CI 代理。我认为 BuildTools SKU 没有工作负载选项,它只是安装所有工作负载所需的所有构建工具。
只有在极少数情况下,CI 代理才需要“完整”Visual Studio,所以除非您知道自己处于那种情况,否则我建议在您的 CI 代理上安装 BuildTools 而不是企业版或专业版。
NuGetCommand
有两个原因。首先,
NuGetCommand
是一个使用 NuGet.exe 的任务。 NuGet.exe 的问题在于,当您使用 PackageReference
而不是 packages.config
时,有时 NuGet 和构建工具(msbuild 的 props/targets)会更改临时文件的文件格式。如果您不使 NuGet.exe 的版本与 MSBuild/Visual Studio 的版本保持一致,您可能会遇到构建错误。所以,使用dotnet restore
会好很多,或者如果你不能使用dotnet cli,那么使用msbuild -t:restore
。这样,您始终可以使用专为安装的 dotnet/msbuild 版本设计的 NuGet 确切版本,并且您永远不必再考虑 NuGet-MSBuild 版本问题。
其次,Azure DevOps 团队的某个人告诉我的团队,他们希望弃用这些“繁重”的任务,并建议客户直接在脚本任务中调用命令。特别是,他们实现这些功能的方式将破坏 NuGet 的新包源映射功能。
如果你的解决方案只包含SDK风格的项目,那么我建议你使用:
- task: NuGetAuthenticate
displayName: Set up NuGet authentication
- script: dotnet restore $(solution)
displayName: Restore
如果您的解决方案包含任何“遗留”(非 SDK 样式)项目,则不要使用 dotnet CLI,而是使用
- script: msbuild -t:restore $(solution)
。
您正在使用任务
VSBuild
来运行您的构建。这是一个使用devenv.com
构建项目的任务。虽然 devenv 确实有命令行参数可以从命令行构建,msbuild.exe
是进行命令行构建的“官方”工具。同样,除非您知道您处于特殊情况下确实需要通过devenv /build
构建,否则我建议您改用dotnet
CLI 或MSBuild
。如前所述,Azure DevOps 团队显然希望弃用“繁重”的任务,因此我建议您使用脚本并直接调用 dotnet
或 msbuild
。
- script: msbuild -t:build $(solution)
displayName: Build solution
“如果任何项目使用 packages.config,那么根据 nuget 的文档,您需要使用 msbuild -t:restore -p:RestorePackagesConfig=true”——这在数小时的挫折之后救了我,最终让我的构建成功.谢谢@zivkan!