无变更时CI/CD流水线NuGet间歇性恢复失败问题求助
未做任何变更的情况下,CI/CD流水线中的NuGet突然出现间歇性失败:执行dotnet test时触发错误NU1301,提示无法加载源https://api.nuget.org/v3/index.json的服务索引,同时反复重试FindPackagesByIdAsync操作,报错Name or service not known (api.nuget.org:443)。
我们使用Sonatype Nexus作为私有源,其他用户流水线均正常,但该问题时好时坏:允许v3源通过时,有时流水线能正常执行(仍会弹出上述报错),有时直接失败。目前未修改任何配置,求可行解决办法。
附带流水线配置:
variables: # Update this for new version builds. - TODO: This will be removed at some point once Jim figures out automatic versioning based on git tags. VERSION: "1.0.$CI_PIPELINE_IID" VERSION_SUFFIX: "$CI_COMMIT_REF_SLUG-$CI_PIPELINE_IID-$CI_COMMIT_SHORT_SHA" # NOTE: If you change your package name, you should also change this to match. PACKAGE_NAME: "Reporting.HoldingQueueReport" image: $CICD_IMAGE stages: - test - deploy - deploy_runner Test: stage: test before_script: - dotnet nuget add source $REPORTS_NUGET_SOURCE -n Nexus - "echo | dotnet --version" # must be v 2.2.300 or later for reporter tool to work - dotnet --info - dotnet restore --verbosity detailed - dotnet tool install dotnet-reportgenerator-globaltool --tool-path tools script: - dotnet test --logger "junit" --collect:"XPlat Code Coverage" # each reporttype must be a separate line, doesn't work together ; separated - ./tools/reportgenerator "-reports:${CI_PROJECT_DIR}/**/TestResults/*/coverage.cobertura.xml" "-targetdir:Reports_Coverage" -reportTypes:TextSummary; - ./tools/reportgenerator "-reports:${CI_PROJECT_DIR}/**/TestResults/*/coverage.cobertura.xml" "-targetdir:Reports_Coverage" -reportTypes:Html; - cat ./Reports_Coverage/Summary.txt - echo 'End Summary' coverage: /Line coverage[\s\S].+%/ artifacts: paths: - Reports_Coverage/ reports: junit: - "*.Test/TestResults/TestResults.xml" - "*.Tests/TestResults/TestResults.xml" NuGet Publish: stage: deploy before_script: # Add our custom NuGet repository group so nuget restore works - dotnet nuget add source $REPORTS_NUGET_SOURCE -n Nexus script: # Pack the project into a NuGet package - dotnet pack -c Release -p:PackageVersion=${VERSION} -o ./build/packages --version-suffix "$VERSION_SUFFIX" --include-symbols - dotnet nuget push ./build/packages/**/*.symbols.nupkg -k ${NEXUS_NUGET_KEY} -s $REPORTS_DEPLOY_NUGET_SOURCE only: - master
1. 禁用默认公共NuGet源,仅使用私有Nexus源
既然已用Nexus作为私有源且其他用户正常,说明Nexus应已代理所需公共包。在流水线的Test和NuGet Publish阶段的before_script中添加移除默认源的命令,避免CI环境尝试访问公共源:
- dotnet nuget remove source "nuget.org" || true
(|| true用于避免源不存在时命令报错中断流水线)
2. 修复CI环境的DNS解析问题
报错Name or service not known指向DNS解析失败,间歇性出现说明CI runner的DNS服务不稳定:
- 临时替换CI环境DNS为公共DNS,在
before_script中添加:
- echo "nameserver 8.8.8.8" > /etc/resolv.conf
- 联系运维检查CI runner所在网络的DNS配置,排查是否存在解析超时或缓存异常。
3. 优化NuGet重试与超时配置
修改NuGet配置,增加重试次数和超时时间,缓解间歇性网络问题:
- dotnet nuget config -set retryCount=5 - dotnet nuget config -set timeout=300
4. 确认Nexus已正确代理公共NuGet源
检查Nexus配置,确认是否创建了nuget.org的代理仓库,并将其加入到你们使用的仓库组中。这样所有包请求都会走Nexus,无需直接访问公共源,从根源避免外部网络问题。
5. 分离restore与test的依赖处理
当前dotnet test会自动触发restore,可能和之前的dotnet restore冲突。修改dotnet test命令,跳过自动restore:
- dotnet test --no-restore --logger "junit" --collect:"XPlat Code Coverage"
确保只使用之前restore好的包,避免重复请求源。
内容的提问来源于stack exchange,提问作者MichaelEvanchik

