管道运行故障排除

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

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

Screenshot of pipeline run summary page.

查看日志

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

Screenshot of task error message on pipeline run summary page.

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

Screenshot of diagnostics log for the pipeline run.

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

Screenshot of log view options in Azure DevOps.

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

“错误分析”页

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

Screenshot of view analysis icon on pipeline run summary page.

Screenshot of view analysis icon for Azure DevOps Server.

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

Screenshot of error analysis page in Azure DevOps portal.

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

Screenshot of task details from error analysis.

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

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

常见问题

失败管道运行的任务见解

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

Screenshot of task insights metrics.

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

Screenshot of task insights for failed pipeline runs setting.

作业超时

管道可能长时间运行,然后由于作业超时而失败。作业超时很大程度上取决于所使用的代理。 对于专用存储库,免费 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

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

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

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

后续步骤