Azure DevOps中Restore Solution步骤失败,求排查解决
问题描述
Azure DevOps Pipelines的Restore Solution步骤本周突然失败,此前运行正常,本地执行解决方案恢复操作无报错。解决方案包含多个项目,其中无需NuGet的Node.js项目schemas.njsproj触发错误:找不到/usr/lib/mono/xbuild/Microsoft/VisualStudio/v16.0/Node.js Tools/Microsoft.NodejsToolsV2.targets,日志显示MSB4019错误。
提供的YAML配置
# ASP.NET # Build and test ASP.NET projects. # Add steps that publish symbols, save build artifacts, deploy, and more: # https://docs.microsoft.com/azure/devops/pipelines/apps/aspnet/build-aspnet-4 trigger: - none pr: - none pool: vmImage: 'ubuntu-latest' variables: buildPath: $(System.DefaultWorkingDirectory)/xxxxx/xxxxx dotNetVersion: '7.x' solution: '**/*.sln' project: '**/xxxxx.csproj' buildPlatform: 'AnyCPU' buildConfiguration: 'Release' workingDirectory: $(Agent.BuildDirectory)/xxxxx/xxxxx/build/bin/Release/net7.0/ stages: - stage: prepare_artifact displayName: 'Prepare Artifact' jobs: - job: "Setup" pool: vmImage: 'ubuntu-latest' steps: - task: NuGetToolInstaller@1 displayName: 'Nuget Tool Installer' - task: NuGetCommand@2 displayName: 'Restore Solution' inputs: restoreSolution: '$(solution)' - task: UseDotNet@2 displayName: 'Use .NET Core SDK' inputs: packageType: 'sdk' version: $(dotNetVersion) - script: | dotnet build --configuration $(buildConfiguration) workingDirectory: $(buildPath) displayName: 'Build' - task: CopyFiles@2 displayName: 'Copy Files' inputs: SourceFolder: $(Build.SourcesDirectory) Contents: '**' TargetFolder: $(Build.ArtifactStagingDirectory) - task: PublishBuildArtifacts@1 displayName: 'Publish Build Artifacts' inputs: PathtoPublish: $(Build.ArtifactStagingDirectory) ArtifactName: 'xxxxx' publishLocation: 'Container'
错误日志
Starting: Restore Solution ============================================================================== Task : NuGet Description : Restore, pack, or push NuGet packages, or run a NuGet command. Supports NuGet.org and authenticated feeds like Azure Artifacts and MyGet. Uses NuGet.exe and works with .NET Framework apps. For .NET Core and .NET Standard apps, use the .NET Core task. Version : 2.222.0 Author : Microsoft Corporation Help : https://docs.microsoft.com/azure/devops/pipelines/tasks/package/nuget ============================================================================== /home/vsts/work/1/s/pipelines/schemas/schemas.njsproj(82,3): error MSB4019: The imported project "/usr/lib/mono/xbuild/Microsoft/VisualStudio/v16.0/Node.js Tools/Microsoft.NodejsToolsV2.targets" was not found. Confirm that the expression in the Import declaration "/usr/lib/mono/xbuild/Microsoft/VisualStudio/v16.0/Node.js Tools/Microsoft.NodejsToolsV2.targets" is correct, and that the file exists on disk. /tmp/NuGetScratchvsts/vluonfw6.ai5.nugetrestore.targets(425,5): warning : Skipping restore for project '/home/vsts/work/1/s/pipelines/schemas/schemas.njsproj'. The project file may be invalid or missing targets required for restore. [/tmp/NuGetScratchvsts/8pyejbwc.yrr.nugetinputs.targets] Detected NuGet version 6.7.0.127 / 6.7.0+b46f5f64159a81d930ac8cdfde96e76f90796c62.b46f5f64159a81d930ac8cdfde96e76f90796c62 /usr/bin/mono /opt/hostedtoolcache/NuGet/6.7.0/x64/nuget.exe sources Add -NonInteractive -Name NuGetOrg -Source https://api.nuget.org/v3/index.json -ConfigFile /home/vsts/work/1/Nuget/tempNuGet_4597108.config Package source with Name: NuGetOrg added successfully. /usr/bin/mono /opt/hostedtoolcache/NuGet/6.7.0/x64/nuget.exe restore /home/vsts/work/1/s/pipelines/pipelines.sln -Verbosity Detailed -NonInteractive -ConfigFile /home/vsts/work/1/Nuget/tempNuGet_4597108.config NuGet Version: 6.7.0.127 MSBuild auto-detection: using msbuild version '15.0' from '/usr/lib/mono/msbuild/15.0/bin'. Use option -MSBuildVersion to force nuget to use a specific version of MSBuild. MSBuild P2P timeout [ms]: 120000 /usr/bin/msbuild "/tmp/NuGetScratchvsts/8pyejbwc.yrr.nugetinputs.targets" /t:GenerateRestoreGraphFile /nologo /nr:false /v:q /p:NuGetRestoreTargets="/tmp/NuGetScratchvsts/vluonfw6.ai5.nugetrestore.targets" /p:RestoreUseCustomAfterTargets="True" /p:DisableCheckingDuplicateNuGetItems="True" /p:RestoreTaskAssemblyFile="/opt/hostedtoolcache/NuGet/6.7.0/x64/nuget.exe" /p:RestoreSolutionDirectory="/home/vsts/work/1/s/pipelines/" /p:RestoreConfigFile="/home/vsts/work/1/Nuget/tempNuGet_4597108.config" /p:SolutionDir="/home/vsts/work/1/s/pipelines/" /p:SolutionName="pipelines" /p:RestoreBuildInParallel="False" /p:RestoreUseSkipNonexistentTargets="False" NuGet.CommandLine.ExitCodeException: Exception of type 'NuGet.CommandLine.ExitCodeException' was thrown. at NuGet.CommandLine.MsBuildUtility.GetProjectReferencesAsync (NuGet.CommandLine.MsBuildToolset msbuildToolset, System.String[] projectPaths, System.Int32 timeOut, NuGet.CommandLine.IConsole console, System.Boolean recursive, System.String solutionDirectory, System.String solutionName, System.String restoreConfigFile, System.String[] sources, System.String packagesDirectory, NuGet.ProjectModel.RestoreLockProperties restoreLockProperties) [0x0048e] in <6484ae034e4e4be89d06d0b5f786e57c>:0 at NuGet.CommandLine.RestoreCommand.GetDependencyGraphSpecAsync (System.String[] projectsWithPotentialP2PReferences, System.String solutionDirectory, System.String solutionName, System.String configFile) [0x0012b] in <6484ae034e4e4be89d06d0b5f786e57c>:0 at NuGet.CommandLine.RestoreCommand.DetermineInputsFromMSBuildAsync (NuGet.CommandLine.RestoreCommand+PackageRestoreInputs packageRestoreInputs) [0x000e5] in <6484ae034e4e4be89d06d0b5f786e57c>:0 ##[error]The nuget command failed with exit code(1) and error(/home/vsts/work/1/s/pipelines/schemas/schemas.njsproj(82,3): error MSB4019: The imported project "/usr/lib/mono/xbuild/Microsoft/VisualStudio/v16.0/Node.js Tools/Microsoft.NodejsToolsV2.targets" was not found. Confirm that the expression in the Import declaration "/usr/lib/mono/xbuild/Microsoft/VisualStudio/v16.0/Node.js Tools/Microsoft.NodejsToolsV2.targets" is correct, and that the file exists on disk. /tmp/NuGetScratchvsts/vluonfw6.ai5.nugetrestore.targets(425,5): warning : Skipping restore for project '/home/vsts/work/1/s/pipelines/schemas/schemas.njsproj'. The project file may be invalid or missing targets required for restore. [/tmp/NuGetScratchvsts/8pyejbwc.yrr.nugetinputs.targets]) ##[error]Packages failed to restore Finishing: Restore Solution
问题原因
- 环境组件缺失:流水线使用
ubuntu-latest镜像,NuGetCommand@2任务默认调用Mono环境下的MSBuild,而Ubuntu镜像未预装Windows环境下Visual Studio专属的Node.js Tools目标文件(Microsoft.NodejsToolsV2.targets),导致解析njsproj时触发文件找不到的错误。 - 命令范围不当:当前
NuGet restore针对整个解决方案(**/*.sln),会遍历所有包含的项目,包括无需NuGet还原的Node.js项目,触发了无效的targets文件查找。 - 环境版本变化:此前流水线正常可能是因为镜像更新或NuGet/MSBuild版本调整,导致现在会严格解析
njsproj中的导入语句,而之前可能自动跳过了非.NET项目的处理。
恢复方案
方案一:缩小NuGet还原范围(推荐)
修改NuGetCommand@2任务的restoreSolution参数,仅针对需要NuGet的.NET项目,使用你已定义的$(project)变量:
- task: NuGetCommand@2 displayName: 'Restore Solution' inputs: restoreSolution: '$(project)'
方案二:修改Node.js项目文件,跳过无效导入
编辑schemas.njsproj文件,为targets导入语句添加条件判断,仅在Windows环境下加载该文件:
<Import Project="$(VSToolsPath)\Node.js Tools\Microsoft.NodejsToolsV2.targets" Condition="Exists('$(VSToolsPath)\Node.js Tools\Microsoft.NodejsToolsV2.targets') AND '$(OS)' == 'Windows_NT'" />
方案三:改用dotnet restore替代NuGetCommand@2
由于后续构建使用dotnet build,改用dotnet restore更适配.NET 7项目,它会自动忽略非.NET类型的njsproj项目:
# 移除原NuGetCommand@2和UseDotNet@2的顺序,调整为以下步骤 - task: UseDotNet@2 displayName: 'Use .NET Core SDK' inputs: packageType: 'sdk' version: $(dotNetVersion) - script: | dotnet restore $(solution) --configuration $(buildConfiguration) workingDirectory: $(buildPath) displayName: 'Restore Solution'
方案四:在Ubuntu代理安装相关组件(不推荐)
由于Microsoft.NodejsToolsV2.targets是Windows专属组件,在Ubuntu环境下安装需要额外配置,步骤繁琐且维护成本高,不建议采用。
内容的提问来源于stack exchange,提问作者delucaezequiel
相关产品推荐
相关产品推荐

