管道运行故障排除

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

如果管道运行无法完成,可以使用管道运行摘要页面提供的诊断信息和日志来帮助排查问题。

管道运行摘要页面的屏幕截图。

查看日志

选择错误消息来查看未能完成的任务的日志。

管道运行摘要页面上任务错误消息的屏幕截图。

将显示日志页面,其中的错误已选定。 在此示例中,cmd-line 任务中存在错误,其中的 echo 命令输入为 ech

管道运行的诊断日志的屏幕截图。

可以通过选择“查看原始日志”来查看任务的原始日志,并且可以使用“查找”在日志中进行搜索。

Azure DevOps 中日志视图选项的屏幕截图。

扫描失败任务的日志,以获取错误信息以及有关任务失败原因的线索。 默认情况下,不详细的日志由管道运行生成。 如果默认日志未指明问题的原因,可以通过配置详细日志来获取更多信息。

“错误分析”页

使用“错误分析”页可以获得问题排查帮助。 将鼠标移到错误信息行上,然后选择“查看分析”图标。

管道运行摘要页面上“视图分析”图标的屏幕截图。

Azure DevOps Server 的视图分析图标的屏幕截图。

对于自托管代理,请选择“查看代理”(对于 Microsoft 托管代理,请选择“关于托管代理映像”)以查看有关用于运行管道的代理的详细信息,然后选择“查看日志”以查看管道运行日志。

Azure DevOps 门户中错误分析页面的屏幕截图。

选择“运行时详细信息”下方的任务的名称以查看有关该任务的信息。

错误分析中任务详细信息的屏幕截图。

在此示例中,可以看到 ScriptValue 中存在错误。 选择“关于此任务”以查看任务的文档。

如果从管道运行摘要页面看不到问题,或在浏览日志时看不到问题,请查看下面的常见问题部分,并参阅查看日志以诊断管道问题,了解如何下载完整日志,其中包含其他诊断信息。

常见问题

失败管道运行的任务见解

Azure DevOps 提供了失败管道运行的任务见解设置,启用该设置后,它会提供生成失败的弹出通知,并提供用于查看报告的链接。

任务见解指标的屏幕截图。

若要配置此设置,请导航到预览功能,找到失败管道运行的任务见解,然后选择所需的设置。

失败管道运行的任务见解设置的屏幕截图。

作业超时

管道可能长时间运行,然后由于作业超时而失败。作业超时很大程度上取决于所使用的代理。 对于专用存储库,免费 Microsoft 托管代理的最大超时时间为每个作业 60 分钟,对于公共存储库,该时间为 360 分钟。 若要增加作业的最大超时时间,可以选择以下任一选项。

  • 购买 Microsoft 托管代理,无论使用的是什么存储库,该代理都将为所有作业提供 360 分钟的时间
  • 使用自托管代理来排除由于代理而导致的任何超时问题

详细了解作业的超时

注意

如果 Microsoft 托管代理作业超时,请确保你没有指定一个小于作业最大超时时间的管道超时时间。 若要检查,请参阅超时

下载代码时出现问题

我的管道在签出步骤中失败

如果对组织中的 Azure Repos Git 存储库使用 checkout 步骤,而该存储库与管道在不同的项目中,请确保禁用“将作业授权范围限制为当前项目”设置,或按照范围内的生成标识中的步骤操作,以确保管道有权访问存储库。

当管道由于作业授权范围有限而无法访问存储库时,你将收到错误 Git fetch failed with exit code 128,并且日志将包含类似于 Remote: TF401019: The Git repository with name or identifier <your repo name> does not exist or you do not have permissions for the operation you are attempting. 的条目

如果管道立即发生故障并显示 Could not find a project that corresponds with the repository,请确保 checkout 步骤或存储库资源声明中的项目和存储库名称正确无误。

Team Foundation 版本控制 (TFVC) 问题

获取的源未下载某些文件

这可能通过来自 tf get 命令的日志中的“所有文件已最新”消息来指明。 验证内置服务标识是否有权下载源。 项目集合生成服务标识或项目生成服务标识都需要权限才能下载源,具体取决于生成管道的“常规”选项卡上选定的授权范围。 在版本控制 Web UI 中,可以在文件夹层次结构的任何级别浏览项目文件,并检查安全设置。

通过 Team Foundation 代理获取源

配置代理以通过 Team Foundation 代理获取源的最简单方法是设置环境变量 TFSPROXY,让它为代理的用户运行指向 TFVC 代理服务器。

Windows:

    set TFSPROXY=http://tfvcproxy:8081
    setx TFSPROXY=http://tfvcproxy:8081 // If the agent service is running as NETWORKSERVICE or any service account you can't easily set user level environment variable

macOS/Linux:

    export TFSPROXY=http://tfvcproxy:8081

我的管道在命令行步骤(如 MSBUILD)上失败

这有助于缩小调查范围,判断生成或发布失败原因是与 Azure Pipelines 还是 TFS 产品问题(代理或任务)有关。 生成和发布失败也可能由外部命令导致。

检查日志,看看失败的任务所执行的确切命令行。 尝试从命令行以本地方式运行命令可能会重现问题。 从自己的计算机以本地方式运行命令和/或登录到计算机并作为服务帐户运行命令,可能会有帮助。

例如,问题是否发生在生成管道的 MSBuild 部分(例如,是否使用了 MSBuildVisual Studio 生成任务)? 如果是这样,请尝试在本地计算机上使用相同的参数运行相同的 MSBuild 命令。 如果可以在本地计算机上重现问题,下一步就是调查 MSBuild 问题。

文件布局

在托管代理上,某个生成所需的工具、库、标头和其他内容的位置可能与本地计算机不同。 如果生成因为找不到其中一个文件而失败,则可以使用以下脚本检查代理上的布局。 这可以帮助你跟踪缺失文件。

在一个临时位置创建新的 YAML 管道(例如,为故障排除而创建的新存储库)。 按照编写的内容,该脚本将搜索路径上的目录。 可以选择编辑 SEARCH_PATH= 行以搜索其他位置。

# Script for Linux and macOS
pool: { vmImage: ubuntu-latest } # or whatever pool you use
steps:
- checkout: none
- bash: |
    SEARCH_PATH=$PATH  # or any colon-delimited list of paths
    IFS=':' read -r -a PathDirs <<< "$SEARCH_PATH"
    echo "##[debug] Found directories"
    for element in "${PathDirs[@]}"; do
        echo "$element"
    done;
    echo;
    echo;  
    echo "##[debug] Found files"
    for element in "${PathDirs[@]}"; do
        find "$element" -type f
    done
# Script for Windows
pool: { vmImage: windows-2019 } # or whatever pool you use
steps:
- checkout: none
- powershell: |
    $SEARCH_PATH=$Env:Path
    Write-Host "##[debug] Found directories"
    ForEach ($Dir in $SEARCH_PATH -split ";") {
      Write-Host "$Dir"
    }
    Write-Host ""
    Write-Host ""
    Write-Host "##[debug] Found files"
    ForEach ($Dir in $SEARCH_PATH -split ";") {
      Get-ChildItem $Dir -File -ErrorAction Continue | ForEach-Object -Process {
        Write-Host $_.FullName
      }
    }

本地命令提示符和代理之间存在差异

请记住,在本地计算机上执行命令以及在代理上运行生成或发布时,一些差异是有效的。 如果代理配置为在 Linux、macOS 或 Windows 上作为服务运行,则它不会在交互式登录会话中运行。 如果没有交互式登录会话,则存在 UI 交互和其他限制。

正在使用的文件或文件夹错误

File or folder in use 错误通常由如下错误消息指明:

  • Access to the path [...] is denied.
  • The process cannot access the file [...] because it is being used by another process.
  • Access is denied.
  • Can't move [...] to [...]

疑难解答步骤:

检测正在使用的文件和文件夹

在 Windows 上,进程监视器等工具可用于捕获特定目录下的文件事件的跟踪。 或者,对于实时快照,可以使用进程资源管理器句柄等工具。

防病毒排除

扫描文件的防病毒软件可能会导致在生成或发布期间出现“文件或文件夹正在使用”的错误。 为代理目录和已配置的“工作文件夹”添加防病毒排除,可能有助于将防病毒软件识别为干扰进程。

MSBuild 和 /nodeReuse:false

如果在生成期间调用 MSBuild,请确保传递参数 /nodeReuse:false(缩写形式为 /nr:false)。 否则,在生成完成后,MSBuild 进程将保持运行状态。 该进程会保留一段时间,以便进行潜在的后续生成。

MSBuild 的这项功能可能会干扰删除或移动目录的尝试,这是因为与 MSBuild 进程的工作目录发生冲突。

MSBuild 和 Visual Studio 生成任务已将 /nr:false 添加到传递给 MSBuild 的参数。 但是,如果你从自己的脚本调用 MSBuild,则需要指定参数。

MSBuild 和 /maxcpucount:[n]

默认情况下,生成任务(如 MSBuildVisual Studio 生成)使用 /m 开关运行 MSBuild。 在某些情况下,这可能会导致问题,例如多个进程文件访问问题。

尝试将 /m:1 参数添加到生成任务,以强制 MSBuild 一次只运行一个进程。

利用 MSBuild 的并发进程功能时,可能会导致“文件正在使用”问题。 不指定参数 /maxcpucount:[n](缩写形式为 /m:[n])的情况会指示 MSBuild 仅使用单个进程。 如果使用 MSBuild 或 Visual Studio 生成任务,可能需要指定“/m:1”来替代默认添加的“/m”参数。

MSBuild 故障断断续续或变化无常

如果遇到间歇性故障或 MSBuild 不一致的故障,请尝试指示 MSBuild 只使用单一进程。 间歇性错误或不一致的错误可能指示目标配置与 MSBuild 的并发进程功能不兼容。 请参阅 MSBuild 和 /maxcpucount:[n]

进程停止响应

进程停止响应的原因和故障排除步骤:

正在等待输入

停止响应的进程可能指示进程正在等待输入。

从交互式登录会话的命令行运行代理,可能有助于确定进程是否以对话方式提示输入。

将代理作为服务运行可能有助于避免程序提示输入的情况。 例如,在 .NET 中,程序可能依赖于 System.Environment.UserInteractive 布尔值来确定是否进行提示。 当代理作为 Windows 服务运行时,该值为 false。

进程转储

分析进程的转储有助于确定死锁进程正在等待的内容。

WiX 项目

在启用自定义 MSBuild 记录器时生成 WiX 项目可能会导致 WiX 死锁等待输出流。 添加额外的 MSBuild 参数 /p:RunWixToolsOutOfProc=true 将解决此问题。

多个平台的行尾

在多个平台上运行管道时,有时可能会遇到具有不同行尾的问题。 在过去,Linux 和 macOS 使用了换行符 (LF),而 Windows 使用了回车加上换行符 (CRLF)。 Git 尝试在存储库中自动使行以 LF 结尾,但在 Windows 上的工作目录中以 CRLF 结尾,通过这种方式来弥补差异。

大多数 Windows 工具都可以仅以 LF 结尾,这种自动行为可能会带来更多的问题,而不是很好地解决问题。 如果遇到行尾相关的问题,建议将 Git 配置为在任何位置都首选 LF。 为此,请将 .gitattributes 文件添加到存储库的根目录中。 在该文件中,添加以下行:

* text eol=lf

变量追加了 '(单引号)

如果管道包含使用 ##vso 命令设置变量的 Bash 脚本,则可能会看到一个额外的 ' 追加到所设置的变量的值。 发生这种情况是因为与 set -x 进行了交互。 解决方法是在设置变量之前暂时禁用 set -x。 用于执行此操作的 Bash 语法为 set +x

set +x
echo ##vso[task.setvariable variable=MY_VAR]my_value
set -x

为何发生这种情况?

许多 Bash 脚本都包含 set -x 命令来辅助调试。 Bash 将准确跟踪已执行的命令,并将其回显到 stdout。 这将导致代理看到 ##vso 命令两次,第二次,Bash 会将 ' 字符添加到末尾。

例如,来看看以下管道:

steps:
- bash: |
    set -x
    echo ##vso[task.setvariable variable=MY_VAR]my_value

在 stdout 上,代理将看到两行:

##vso[task.setvariable variable=MY_VAR]my_value
+ echo '##vso[task.setvariable variable=MY_VAR]my_value'

当代理看到第一行时,MY_VAR 将设置为正确的值“my_value”。 但是,当代理看到第二行时,它将处理追加到行尾的所有内容。 MY_VAR 将设置为“my_value'”。

脚本执行时没有为 Python 应用程序安装库

部署 Python 应用程序时,在某些情况下,CI/CD 管道将运行且代码部署成功,但负责安装所有依赖项库的 requirements.txt 文件不会执行。

若要安装依赖项,请在应用服务部署任务中使用部署后脚本。 下面的示例展示了必须在部署后脚本中使用的命令。 可以为实际场景更新脚本。

D:\home\python364x64\python.exe -m pip install -r requirements.txt

若要排查与服务连接相关的问题,请参阅服务连接故障排除

管道停止从代理接收信息

如果管道失败并显示类似”We stopped hearing from agent <agent name>. Verify the agent machine is running and has a healthy network connection.“的消息,则请检查代理的资源利用率,以查看代理计算机是否已耗尽资源。 从 Sprint 228 开始,Azure Pipelines 日志包含每个步骤的资源利用率指标

在使用 Azure DevOps Services 时,启用 verbose logs 可以查看日志中的资源利用率,包括磁盘使用情况、内存使用情况和 CPU 利用率。 在管道完成后,请搜索日志以查找每个步骤的 Agent environment resources 条目。

2024-02-28T17:41:15.1315148Z ##[debug]Agent environment resources - Disk: D:\ Available 12342.00 MB out of 14333.00 MB, Memory: Used 1907.00 MB out of 7167.00 MB, CPU: Usage 17.23%

有关捕获其他资源利用率日志的信息,请参阅捕获资源利用率详细信息

允许存储资源管理器通过 Azure Pipelines 将静态内容(如 .css 和 .js)从 Azure DevOps 部署到静态网站

在此场景中,可以使用 Azure 文件复制任务将内容上传到网站。 可以使用上传内容中所述的任何工具将内容上传到 Web 容器。

后续步骤