mcpField
F
fix-ci-failures

fix-ci-failures

github.com/microsoft云与 DevOps194.4k207 次安装今天更新
代码仓库

关于 fix-ci-failures

使用 `gh` 命令行诊断并修复拉取请求中的 CI 失败,面向负责维护代码的开发者。流程涵盖检查失败任务、分析日志,并判断问题源自代码还是基础设施。

主要功能

  1. 01查找当前分支对应的拉取请求
  2. 02检查状态并定位失败任务
  3. 03查看任务日志和构建产物
  4. 04区分代码问题与基础设施故障
  5. 05修复更改并重新运行 CI

适用场景

  1. 01调查拉取请求检查失败
  2. 02从已完成或运行中的任务日志定位错误
  3. 03判断失败是否由偶发或基础设施问题导致

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/microsoft/vscode --skill fix-ci-failures

安装后在 Claude Code 中输入/fix-ci-failures确认已加载。

详细介绍

调查并修复 CI 失败

本技能将引导你使用 gh CLI 诊断并修复 PR 上的 CI 失败。用户已在本地检出 PR 分支。

工作流概览

  1. 确认当前分支及其 PR
  2. 检查 CI 状态并找出失败的检查
  3. 下载失败任务的日志
  4. 提取并理解失败原因
  5. 修复问题并推送

第 1 步:确认分支和 PR

# Get the current branch name
git branch --show-current

# Find the PR for this branch
gh pr view --json number,title,url,statusCheckRollup

如果未找到 PR,用户可能需要指定 PR 编号。


第 2 步:检查 CI 状态

# List all checks and their status (pass/fail/pending)
gh pr checks --json name,state,link,bucket

# Filter to only failed checks
gh pr checks --json name,state,link,bucket --jq '.[] | select(.bucket == "fail")'

link 字段包含 GitHub Actions 任务的 URL。从 URL 中提取 运行 ID——即 /runs/ 后面的数字:

https://github.com/microsoft/vscode/actions/runs/<RUN_ID>/job/<JOB_ID>

如果检查仍处于 IN_PROGRESS 状态,请等待其完成后再下载日志:

gh pr checks --watch --fail-fast

第 3 步:获取失败任务的详细信息

# List failed jobs in a run (use the run ID from the check link)
gh run view <RUN_ID> --json jobs --jq '.jobs[] | select(.conclusion == "failure") | {name: .name, id: .databaseId}'

第 4 步:下载失败日志

根据失败类型,有两种处理方式。

选项 A:直接查看失败步骤的日志

适用于构建/编译/代码检查失败,且错误出现在步骤输出中的情况:

# View only the failed step logs (most useful — shows just the errors)
gh run view <RUN_ID> --job <JOB_ID> --log-failed

重要提示:--log-failed 要求整个运行都已完成,而不仅仅是失败的任务。如果其他任务仍在运行,此命令会一直等待或报错。如果运行仍在进行,但任务已完成,请使用下方的选项 C获取日志。

输出可能很大。可以通过 tail 或 grep 管道筛选重点内容:

# Last 100 lines of failed output
gh run view <RUN_ID> --job <JOB_ID> --log-failed | tail -100

# Search for common error patterns
gh run view <RUN_ID> --job <JOB_ID> --log-failed | grep -E "Error|FAIL|error TS|AssertionError|failing"
选项 B:下载构件

适用于集成测试失败,且详细日志(终端日志、扩展主机日志、崩溃转储)作为构件上传的情况:

# List available artifacts for a run
gh run download <RUN_ID> --pattern '*' --dir /dev/null 2>&1 || gh run view <RUN_ID> --json jobs --jq '.jobs[].name'

# Download log artifacts for a specific failed job
# Artifact naming convention: logs-<platform>-<arch>-<test-type>-<attempt>
# Examples: logs-linux-x64-electron-1, logs-linux-x64-remote-1
gh run download <RUN_ID> -n "logs-linux-x64-electron-1" -D /tmp/ci-logs

# Download crash dumps if available
gh run download <RUN_ID> -n "crash-dump-linux-x64-electron-1" -D /tmp/ci-crashes

提示:使用失败检查中的测试运行器名称(例如,“Electron / Linux”→ electron,“Remote / Linux”→ remote)和平台映射(“Windows”→ windows-x64,“Linux”→ linux-x64,“macOS”→ macos-arm64)来构造构件名称。

警告:如果测试运行器在生成输出前崩溃(例如,Electron 下载失败),日志构件可能为空。此时请改用选项 C。

选项 C:通过 API 下载每个任务的日志(运行进行中时也可用)

如果运行仍在进行,但失败的任务已完成,请使用 GitHub API 直接下载该任务的步骤日志:

# Save the full job log to a temp file (can be very large — 30k+ lines)
gh api repos/microsoft/vscode/actions/jobs/<JOB_ID>/logs > "$TMPDIR/ci-job-log.txt"

然后搜索保存的文件。先查找 ##[error]——这是 GitHub Actions 的错误注释,用于标记步骤失败的确切行:

# Step 1: Find the error annotation (fastest path to the failure)
grep -n '##\[error\]' "$TMPDIR/ci-job-log.txt"

# Step 2: Read context around the error (e.g., if error is on line 34371, read 200 lines before it)
sed -n '34171,34371p' "$TMPDIR/ci-job-log.txt"

如果 ##[error] 未能提供足够信息,请使用范围更广的匹配模式:

# Find test failures, exceptions, and crash indicators
grep -n -E 'HTTPError|ECONNRESET|ETIMEDOUT|502|exit code|Process completed|node:internal|triggerUncaughtException' "$TMPDIR/ci-job-log.txt" | head -20

为何要保存到文件? 完整任务日志的 API 响应可能超过 3 万行。工具输出会被截断,因此请务必先将内容重定向到文件,再进行搜索。

VS Code 日志构件结构

下载的日志构件通常包含:

logs-linux-x64-electron-1/
  main.log              # Main process log
  terminal.log          # Terminal/pty host log (key for run_in_terminal issues)
  window1/
    renderer.log        # Renderer process log
    exthost/
      exthost.log       # Extension host log (key for extension test failures)

优先检查以下关键文件:

  • 测试断言失败:检查 exthost.log 中的扩展主机输出和堆栈跟踪
  • 终端/沙盒问题:检查 terminal.log 中的重写器管道、Shell 集成和策略日志
  • 崩溃/挂起:检查 main.log,并查找崩溃转储构件

第 5 步:提取失败原因

对于测试失败

在失败步骤日志中查找测试运行器输出:

# Find failing test names and assertion messages
gh run view <RUN_ID> --job <JOB_ID> --log-failed | grep -A 5 "failing\|AssertionError\|Expected\|Unexpected"

VS Code CI 中的常见模式:

  • AssertionError [ERR_ASSERTION]:测试断言失败——检查预期值和实际值
  • Extension host test runner exit code: 1:集成测试套件存在失败项
  • Command produced no output:Shell 集成可能未捕获命令输出(参见 terminal.log)
  • Error: Timeout:测试超时——可能是挂起,也可能是 CI 机器运行缓慢
对于构建失败
# Find TypeScript compilation errors
gh run view <RUN_ID> --job <JOB_ID> --log-failed | grep "error TS"

# Find hygiene/lint errors
gh run view <RUN_ID> --job <JOB_ID> --log-failed | grep -E "eslint|stylelint|hygiene"

步骤 6:确定失败是否与 PR 有关

修复前,先确定失败是由 PR 更改导致的,还是由已有问题/基础设施问题导致的:

  1. 检查失败的测试是否位于你修改的代码中 — 如果测试位于完全无关的区域,可能是偶发失败
  2. 检查测试名称 — 它是否与您修改的功能区域相关?
  3. 查看失败输出 — 它是否引用了 PR 涉及的代码路径?
  4. 检查 main 上的相同测试是否也失败 — 如果近期的 main 提交中存在相同失败,则这是已有问题
  5. 查找基础设施故障 — 网络超时、npm registry 错误和机器级问题都不是由代码更改导致的
# Check recent runs on main for the same workflow
gh run list --branch main --workflow pr-linux-test.yml --limit 5 --json databaseId,conclusion,displayTitle
识别基础设施故障/偶发失败

并非所有 CI 失败都是由代码更改导致的。常见的基础设施故障包括:

网络/Registry 问题:

  • npm ERR! network、ETIMEDOUT、ECONNRESET、EAI_AGAIN — 无法访问 npm registry
  • error: RPC failed; curl 56、fetch-pack: unexpected disconnect — git 网络故障
  • Error: unable to get local issuer certificate — TLS/证书问题
  • rate limit exceeded — GitHub API 触发速率限制
  • electron/electron/releases 上出现 HTTPError: Request failed with status code 502 — Electron CDN 下载失败(常见于 node.js integration tests 步骤,该步骤会在运行时下载 Electron)

机器/环境问题:

  • No space left on device — CI 磁盘空间不足
  • ENOMEM、JavaScript heap out of memory — CI 机器内存不足
  • The runner has received a shutdown signal — CI 抢占/超时
  • Error: The operation was canceled — GitHub Actions 取消了作业
  • Xvfb failed to start — 无头 Linux 测试所需的显示服务器启动失败

测试偶发失败(不是基础设施问题,但也不是你的过错):

  • 通常会通过的测试超时 — CI 机器运行缓慢
  • 异步测试中的竞态条件
  • Shell 集成未报告退出代码(在 terminal.log 中查找 exitCode: undefined)

基础设施故障的处理方法:

  1. 不要更改代码 — 失败不是由你的 PR 导致的
  2. 通过 GitHub UI 或以下命令重新运行失败的作业:
    gh run rerun <RUN_ID> --failed
    
  3. 如果重新运行后仍然失败,检查 main 是否也有问题:
    gh run list --branch main --limit 10 --json databaseId,conclusion,displayTitle
    
  4. 如果 main 也有问题,请等待修复 — 你的 PR 不是原因

步骤 7:修复并迭代

  1. 在本地进行修复
  2. 验证编译:检查 VS Code - Build 任务,或运行 npm run typecheck-client
  3. 在本地运行相关单元测试:./scripts/test.sh --grep "<pattern>"
  4. 提交并推送:
    git add -A
    git commit -m "fix: <description>"
    git push
    
  5. 再次检查 CI:
    gh pr checks --watch --fail-fast
    

快速参考

任务命令
查找分支对应的 PRgh pr view --json number,url
列出所有检查gh pr checks --json name,state,bucket
仅列出失败的检查gh pr checks --json name,state,link,bucket --jq '.[] | select(.bucket == "fail")'
持续监视检查直到完成gh pr checks --watch --fail-fast
查看某次运行中的失败作业gh run view <RUN_ID> --json jobs --jq '.jobs[] | select(.conclusion == "failure") | {name, id: .databaseId}'
查看失败步骤的日志gh run view <RUN_ID> --job <JOB_ID> --log-failed(需要完整运行结束)
通过 API 下载作业日志gh api repos/microsoft/vscode/actions/jobs/<JOB_ID>/logs > "$TMPDIR/ci-job-log.txt"(运行进行中也可使用)
在日志中查找错误行grep -n '##\[error\]' "$TMPDIR/ci-job-log.txt"
下载日志工件gh run download <RUN_ID> -n "<artifact-name>" -D /tmp/ci-logs
重新运行失败的作业gh run rerun <RUN_ID> --failed
查看 main 的近期运行gh run list --branch main --workflow <workflow>.yml --limit 5

评论

支持 Markdown