尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Flutter 开源仓库 PR 失败检查修复指南:tree-status、Google Testing、ci.yaml 校验与 Flaky 排查实战

Flutter 开源仓库 PR 失败检查修复指南:tree-status、Google Testing、ci.yaml 校验与 Flaky 排查实战 Flutter 开源仓库 PR 失败检查修复指南tree-status、Google Testing、ci.yaml 校验与 Flaky 排查实战【免费下载链接】flutterFlutter makes it easy and fast to build beautiful apps for mobile and beyond项目地址: https://gitcode.com/GitHub_Trending/flutter41/flutter本文基于 Flutter 仓库贡献文档 How to fix a PRs failing checks 展开系统讲解向 flutter/flutter 仓库提交 Pull Request 时各类失败检查failing checks的含义与修复手段如何区分 tree-status、Google Testing、ci.yaml validation 与真实代码缺陷导致的失败如何阅读 LUCI 测试输出定位失败用例并本地复现以及如何处理随机失败flaky与基础设施错误。读完后你可以独立完成 PR 检查失败的分类、排查、rebase 修复与阻塞跟进的完整闭环。PR 失败检查的分类与排查总览在 Flutter 仓库每个 PR 底部都会挂着一组 check run其中几类失败检查的成因和处置方式完全不同混在一起看容易做无用功。原文档将其归为四类本文按此骨架展开失败检查失败本质修复动作tree-status与 PR 无关反映main 分支的健康状态无需在 PR 内改动满足评审条件后由 reviewer 加autosubmit标签等树变绿后机器人自动合入Google testing可能是 flake也可能是 PR 引入了破坏性变更联系 Google 员工查看内部测试输出通常修改 PR 为非破坏性变更已批准的破坏性变更须走 breaking change 流程ci.yaml validation根目录 .ci.yaml 与 base 分支失去同步将 master 最新变更应用到 PR推荐rebase而非 merge commitA bug in the PRPR 自身代码破坏了既有行为含customer_testing、Linux Analyze等查看测试输出、定位失败用例、本地复现并修复另有一类横切问题——flaking随机失败单独在最后讨论。下面的每个小节都对应原文档的一个章节并结合仓库中的真实文件与文档补充了源码级佐证。tree-status与 PR 无关的“红绿灯”tree-status是 PR 上最特殊的一个 check它检查的不是你的 PR而是main 分支当前是否通过检查。原文档明确说明Unlike other checks,tree-statusisnt tied to the pull request: instead, it shows whether checks are passing in the main branch.失败可能由多种原因造成且应当优先于其他任何合入被解决。因此作者侧的正确动作不是改代码而是走合入流程等待放行满足评审要求LGTM、CLA 等其他所有 check 全部通过reviewer 为 PR 添加autosubmit标签机器人Auto-submit bot在tree-status 变绿后自动合入该 PR。仓库文档 Using the Auto-submit Bot 给出了 Auto-submit bot 响应的标签定义可作为上述流程的权威参照标签作用谁来加autosubmit树变绿时合入 PR人工revert对已合入的 PR 发起回滚人工revert of追踪由 revert 请求生成的新 PRBotemergency绕过 tree-status 检查在树关闭时强行合入人工且必须与autosubmit联用对应的验证条件包括CI checks、来自 flutter-hackers 的 2 个 approval、以及 mergeability。特别注意文档中的警告emergency不能单独使用只有当你的 PR 本身就是修复当前树故障的方案时才可使用否则必须等树重新变绿。这解释了为什么 tree-status 失败时普通 PR“干等”是唯一正确姿势。Google Testing 失败flake 还是破坏性变更Google Testing 是一个 presubmit 检查在大多数 PR 上运行 Google 内部测试的一个子集用以验证“当前 Flutter 仓库状态 本 PR 应用之后”这些内部测试是否仍然通过。它失败时只有两种可能这是一个 flake见本文最后一节PR 的改动破坏了内部测试。原文档给出的处置路径Google 员工可以查看测试输出并给出反馈。如果你的 reviewer 是 Googler直接在 PR 上 ping 他如果不是去 Discord 的#hackers频道求助。正确的做法“很可能”是继续修改 PR使其成为非破坏性变更non-breaking。破坏性变更会给用户带来 churn改造成本、侵蚀整个生态所以多数情况下更新为非破坏性变更才是解锁 PR 的正道。如果该破坏性变更确实被批准了则必须遵循 breaking change 策略变更在可能时应当附带dart fix数据驱动的自动修复否则需要撰写迁移指南migration guide。被 Google Testing 阻塞的 PR 会统一跟踪在Google testing queue project中按 FIFO 顺序处理如果你的 PR 没有被加入该 project 跟踪去 ping 你的 reviewer。两周后仍无人处理原文档明确授权此时可以直接 在 Discord 上求助。源码与文档佐证Google Testing 的流水线与常见 FAQUnderstanding Google Testing 文档见其 “Validation Pipeline” 一节细化了这个检查的执行阶段便于你在等待时判断卡在哪个环节触发 1 分钟需要 flutter-hackers 成员 approval 后才触发Google 员工则立即运行由 GitHub webhook 驱动等待引擎构建约 40 分钟若 PR 更新了 engine需等 Flutter CI 先构建引擎产物冒烟测试约 10 分钟选取一部分测试作为 presubmit 冒烟套件为 PR 提供快速、高覆盖的反馈更大测试套件30–90 分钟冒烟通过后运行繁忙时段可能长达数小时。同一文档的 “Common issues” 一节还补充了原文档未展开的几个高频场景预期内的 golden file 失败由 Googler 确认是预期改动后可在内部把该 check 手动置为通过非 golden 的失败但属于有意为之若改动量不大十几个文件内的修改作者或 reviewer若为 Googler应提交 “g3fix” 或直接修进 roll CL使状态回到绿色若双方都不可用roller 可能会选择 revert 该 PRGoogle testing 报 merge conflict 但 GitHub 显示没有Google testing 使用的 merge base 通常落后 GitHub 若干 commit几小时后再 rebase 或用 check run UI 重跑即可与 PR 无关的测试失败 / 基础设施问题用 check run UI 重跑若由 failing 变为 passing会被标记为flake。ci.yaml validation保持 .ci.yaml 与 base 分支同步要让检查正确运行仓库根目录的 .ci.yaml 必须与base 分支保持同步——一旦上游修改了 CI 配置而你的 PR 还基于旧版本这个校验就会失败。修复方法原文档 What to do把 master 的最新变更应用到你的 PR 上。原文档同时提示Tree hygiene 页推荐使用rebase 而不是 merge commit来更新 PR。仓库文档 Tree hygiene 的 “Using git” 一节给出了具体命令并解释了为何必须 rebasegit fetch upstream git rebase upstream/main git push origin your_branch_name原因是 Flutter 的 CI 工具链会将 rebase 后的 PR 识别为“最新状态”若使用 merge工具会尝试针对你最初分支时点的测试基线去跑检查造成基线漂移。源码佐证.ci.yaml 是什么从仓库中真实的 .ci.yaml 文件可以确认其结构与原文档说法一致。文件头部注释说明Describes the targets run in continuous integration environment. … Flutter infra uses this file to generate a checklist of tasks to be performed for every commit.其中enabled_branches见 .ci.yaml 第 14–16 行声明了 CI 生效的分支enabled_branches: - master - flutter-\d\.\d-candidate\.\d随后是各平台linux、linux_android_emu等的platform_properties以 JSON 形式锁定依赖版本如android_sdk、open_jdk、gradle_dists的精确版本号。正因为这些依赖版本会随主干持续滚动升级PR 分支上的旧配置就会与 base 分支产生 diff——这正是 ci.yaml validation 检查失败、需要 rebase 同步的根因。A bug in the PR检查失败是 PR 自身代码的问题这是最常见的失败类型改动无意间破坏了既有行为。原文档给出的第一要务是查看测试输出见下文“查看测试输出”一节然后按失败的具体 check 对症下药customer_testing 失败customer_testingcheck 未通过意味着Flutter 客户测试注册表customer test registry中有测试失败了。该注册表包括包测试以及其他开源 Flutter 项目的测试。关键点If a pull request requires an update to those external tests, it qualifies as abreaking change; please avoid those when possible.也就是说如果你的 PR 需要去改那些外部仓库的测试它就在 破坏性变更策略 的定义范围内应尽可能避免。仓库文档 Tree hygiene — Handling breaking changes 给出了完整流程佐证所谓 “contributed tests” 包括 PR 上的customer_testingshard 以及若干万级不可公开的 Google 内部测试破坏其中任何一个都算 breaking change没有豁免因为这些测试在 CI 上运行破坏它们会关闭树。后续五步流程判定 → 评估 → 以 opt-in 方式准备变更 → 分阶段落地 → 撰写迁移指南并公告与Deprecated的标准语法必须包含迁移说明、破坏 API 的简述、以及 “This feature was deprecated after v[版本号]” 三要素都可以直接查阅该节。Linux Analyze 失败Linux Analyze失败多半是 PR 中的某些改动违反了 Dart linter 规则。原文档建议参照 框架开发环境搭建文档 配好本地环境这样大部分问题能在静态分析阶段就地发现而不是等 CI 报出来。原文档还有一段值得强调的 NOTEAll Dart code is run through static analysis: this includesmarkdown code snippets in doc comments!也就是说即使你只改了文档注释其中的 markdown 代码片段同样会被静态分析覆盖——这是不少“只改文档却挂 Analyze”的 PR 的根因。查看测试输出View the test output定位“PR 自身 bug”的核心动作是阅读完整测试输出原文档的操作路径为点击失败 check 的Details再点击View more details on flutter-dashboard进入 LUCI 概览页后页面底部会给出完整测试输出的链接。原文档附上了一段典型的失败输出它展示了如何从异常信息反查失败用例。保留这段示例以便对照══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════ The following TestFailure was thrown running a test: Expected: exactly one matching candidate Actual: _TextWidgetFinder:Found 0 widgets with text AsyncSnapshotString(ConnectionState.waiting, null, null, null): [] Which: means none were found but one was expected When the exception was thrown, this was the stack: #4 main.anonymous closure.anonymous closure (…/packages/flutter/test/widgets/async_test.dart:115:7) asynchronous suspension #5 testWidgets.anonymous closure.anonymous closure (package:flutter_test/src/widget_tester.dart:189:15) asynchronous suspension #6 TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:1032:5) asynchronous suspension asynchronous suspension (elided one frame from package:stack_trace) This was caught by the test expectation on the following line: file:///b/s/w/ir/x/w/flutter/packages/flutter/test/widgets/async_test.dart line 115 The test description was: gracefully handles transition from null future ════════════════════════════════════════════════════════════════════════════════════════════════════从这段输出可以提取三个定位线索失败用例所在的文件与行号async_test.dart:115、期望与实际的不匹配expected exactly one ... Found 0 widgets、以及测试描述gracefully handles transition from null future。拿到它们之后按原文档的说法“剩下的只是找到失败的测试、在本地运行它、然后想办法修好”本地运行与编写单测的完整方法见 Running and writing tests对test/目录下所有*_test.dart使用flutter test针对单个文件可用flutter test lib/my_app_test.dart如需像 LUCI 一样在本地跑全仓库的分析和测试可执行dart dev/bots/test.dart与dart --enable-asserts dev/bots/analyze.dart两个入口分别对应仓库中的 dev/bots/test.dart 与 dev/bots/analyze.dart后者正是Linux Analyze检查背后的分析脚本。Flaking随机失败的识别与处理检查可能因为各种原因随机失败flake。原文档给出两条处理建议推送新改动重新触发检查有时 flake 会自行消失。可以考虑 执行一次 rebase 以纳入 main 分支的最新变更即复用上文 ci.yaml validation 一节的git fetch upstream; git rebase upstream/main; git push origin branch流程。Flake 往往源于基础设施错误infra errors。查看与上报 infra bug 的方法参见 LUCI 构建失败文档中的 infra failure 概览。该文档见其 “Overview of an infra failure build” 一节进一步佐证了 flake 的排查要点Infra failure 的典型成因网络连接问题、硬件故障、recipe 损坏、CIPD 依赖问题等在构建面板上显示为紫色框区别于测试失败的红色框排查步骤先点击构建历史链接确认该 infra failure 是否在更早的构建中也出现过 → 检查 infra bug pool 是否已有同类问题 → 没有则提交一个 infra bug → 需要即时帮助可去 Discord 的hackers-infra频道重跑rerun权限限制presubmit 的重跑仅限flutter-hackers组成员无权限时可在#hackers-infra频道请团队成员代跑post-submit 的重跑目前受基础设施限制仅限 Google 员工操作。这解释了原文档“flake 往往由 infra errors 引起”的判断依据很多看起来像测试失败的随机红框实际是基础设施抖动导致的紫框正确动作是重跑或上报 infra bug而不是改代码。排查速查与延伸阅读把全文收敛为一张决策表供 PR 失败时快速对号入座tree-status 红→ 不是你的锅。确认评审与其余 check 全绿等待 reviewer 加autosubmit机器人等树变绿后自动合入修复树的 PR 才允许autosubmitemergency。Google testing 红→ ping reviewer非 Googler 则去 Discord#hackers优先把 PR 改成非破坏性已批准的 breaking change 必须带 dart fix 或迁移指南两周无人处理则主动求助。ci.yaml validation 红→ rebase 到最新upstream/main再 push不要用 merge commit。customer_testing / Linux Analyze / 具体测试失败红→ 打开 Details → flutter-dashboard 拿完整日志 → 按失败栈定位用例 →flutter test本地复现修复需要改外部测试 breaking change走五步流程。时红时绿→ 先重跑确认是否 infra failure紫框、历史构建复现是则查/报 infra bug重跑受限就找#hackers-infra。延伸阅读均为仓库内文档相对路径How to fix a PRs failing checks本文对应的原始文档Tree hygiene评审、git 使用、breaking change 处理Using the Auto-submit Botautosubmit/emergency/revert标签语义Understanding Google Testing内部测试检查的流水线与 FAQUnderstanding a LUCI build failureinfra failure 与 test failure 的区分及重跑流程Running and writing testsflutter test与全仓库测试入口Setting up the Framework development environment让静态分析问题在本地就被拦下Understanding Packages testscustomer test registry 中的包测试.ci.yamlCI 任务清单的源头文件【免费下载链接】flutterFlutter makes it easy and fast to build beautiful apps for mobile and beyond项目地址: https://gitcode.com/GitHub_Trending/flutter41/flutter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表