flutter_flutter 仓库 LUCI 构建失败排查指南:从构建仪表盘到 Infra/Test 故障处置

发布时间:2026/10/15 16:53:17

flutter_flutter 仓库 LUCI 构建失败排查指南:从构建仪表盘到 Infra/Test 故障处置 跨平台前端移动开发OpenHarmony【免费下载链接】flutter_flutter本仓库是 Flutter SDK 与 Flutter Engine 的 OpenHarmony 适配版本由 CPF-Flutter 团队维护。开发者可使用熟悉的 Flutter 技术栈开发 OpenHarmony 应用3.35.7 及以后的适配版本可基于本仓库源码构建支持 OpenHarmony 的 Flutter Engine。项目地址https://gitcode.com/CPF-Flutter/flutter_flutter点击查看免费下载导读本文面向在 flutter_flutterFlutter SDK 与 Flutter Engine 的 OpenHarmony 适配版仓库中提交代码、运行 CI 的开发者与维护者系统讲解基于 LUCILayered Universal Continuous Integration分层通用持续集成的构建失败排查方法。读完本文你将掌握如何区分「基础设施故障Infra Failure」与「测试失败Test Failure」如何在构建仪表盘与 LUCI 构建详情页中定位真正的失败步骤以及针对 pre-submit / post-submit 两种场景下正确的重跑Re-run / RERUN与故障上报流程并了解本仓库中.ci.yaml与dev/bots/test.dart等配置如何驱动这些构建任务。一、LUCI 与 Flutter 构建仪表盘先了解构建从哪来在 flutter_flutter 仓库中绝大多数测试都运行在 Flutter 的 CI 系统LUCILayered Universal Continuous Integration之上覆盖多个 Flutter 仓库的多种场景包括post-submit提交后代码合入主分支后运行覆盖 framework 主分支的构建与测试pre-submit提交前 / tryPull Request 触发用于在合入前验证变更此外还有 devicelab 真机性能测试、benchmark 等任务。从仓库源码看LUCI 构建由两份.ci.yaml文件驱动参见 dev/bots/README.md框架framework侧配置根目录的 .ci.yaml其中包含enabled_branches、platform_properties和targets三大部分定义了每个构建目标builder的名称、recipe、超时时间、依赖如 android_sdk、open_jdk、chrome_and_driver 等、shard 与 subshard 划分以及presubmit_max_attemptspre-submit 最大重试次数等字段引擎engine侧配置engine/src/flutter/.ci.yaml。在 .ci.yaml 中可以看到一个典型 target 的定义例如Linux analyzetargets: - name: Linux analyze recipe: flutter/flutter_drone timeout: 60 properties: shard: analyze dependencies: - [ {dependency: ktlint, version: version_1_5_0}, {dependency: open_jdk, version: version:21} ] tags: [framework,hostonly,shard,linux]其中recipe: flutter/flutter_drone表示该构建目标最终会委托给本仓库的 dev/bots/test.dart 执行shard字段决定具体运行哪个测试分片shard。查看构建结果的入口有两个下文提到的 Flutter 构建仪表盘与 LUCI Milo 仪表盘均以 framework 为例Flutter 构建仪表盘Flutter build dashboard用于查看 post-submit framework 构建结果的总体视图LUCI Milo 仪表盘LUCI 底层的构建详情视图展示每个 builder 的构建记录、步骤列表与日志。二、Infra Failure基础设施故障紫色方块Infra Failure基础设施故障指并非由被测代码引起的构建失败典型诱因包括网络连接问题、硬件宕机、recipe构建配方脚本本身出错、cipd 依赖问题等。这类失败在构建仪表盘中显示为紫色方块post-submit 构建仪表盘中失败任务显示为紫色方块与相邻的绿色通过方块形成对比pre-submit 构建控制台中失败项同样以紫色矩形标示。2.1 一个 Infra Failure 构建的概览视图以示例构建Linux color_filter_and_fade_perf__e2e_summary为例在 LUCI 构建概览页中通常包含以下关键区域(i) 该 builder 的历史构建列表链接用于快速对比「之前是否也失败过」(ii) 失败原因的快速预览给出本次失败属于哪一类问题(iii) 步骤列表该 builder 的构建步骤由右侧显示的 recipe 定义(iv) 真正导致失败的步骤即需要重点关注的失败点(v)stdout日志点击进入详细日志是定位根因的主要材料。需要特别强调的是概览页显示的失败原因可能与真实失败步骤不同。Infra failure 往往表现为某个下游步骤如安装依赖、拉取缓存、连接设备失败因此必须通过 (iii) 的步骤列表定位到 (iv) 真正失败的步骤并阅读 (v) 的 stdout 日志确认根因。2.2 Infra Failure 的标准处置流程当遇到紫色Infra失败时按以下顺序处置确认是否为偶发点击 (i) 查看该 builder 更早的构建记录判断该失败是否在历史构建中反复出现检索既有 issue在infra bug 池带team: infra标签的公开 issue 列表中检查是否已有对应问题被报告新建 bug若不存在则使用 infrastructure 模板提交一个新的 infra bug附上失败的构建链接与相关日志寻求即时帮助如需即时协助可以在 Discord 的hackers-infra频道提问判定为 flake 后重跑如果确认属于 infra flake基础设施偶发抖动则触发重跑详见下文「重跑Re-run / RERUN操作指南」。2.3 Infra 相关的源码佐证从仓库源码可以进一步理解 infra 层如何运转dev/bots/README.md 明确指出LUCI 机器人为每个 PR 与提交运行 test.dart 脚本完成工具、框架测试并对已合入的变更重建与更新主分支 API 文档站点同时该文档还说明 infra 重触发构建需要特殊权限需提交team-infraissue 申请Flutter-Infrastructure-Foundation.md 记录了底层基础设施的构成DeviceLab 真机测试床Android/iOS/桌面多平台、自动供应的 Linux/Windows 虚拟机分布于luci.flutter.prod、luci.flutter.try、luci.flutter.staging、luci.dart-internal.flutter等 pool、SALT 配置供应服务、LUCI swarming bot 等——理解这些有助于判断「机器/网络/依赖」层面的故障.ci.yaml 中的platform_properties为每个平台定义了依赖与机器规格例如staging_build_linux声明了 curl 依赖、8 核、ignore_flakiness: true忽略偶发失败等属性这些字段直接影响 infra 故障是否会被自动忽略。三、Test Failure测试失败红色方块Test Failure测试失败指由代码变更或测试本身引起、可复现的真实失败在构建仪表盘中显示为红色方块post-submit 构建仪表盘中失败任务显示为红色方块pre-submit 构建控制台中失败项同样以红色矩形标示。Test failure 的构建概览页与 infra failure 相同参见上文 (i)–(v) 的说明但关注点不同Test failure 需要重点阅读错误信息 (ii) 与详细日志 (v)确认是否是代码变更导致的真实失败。3.1 Test Failure 的标准处置流程判断是否为新引入通过 (i) 查看该 builder 更早的构建/提交记录判断失败是否由本次变更引入本地调试基于错误信息 (ii) 与详细日志 (v) 定位失败测试在本地复现并修复检索既有 issue在 issue 列表中检查该失败是否已被报告检索 flake 记录在带c: flake标签的 flaky issues 列表中检查是否已有对应的偶发失败记录提交新 bug如确属新问题按规范提交 bug附测试名、失败日志、出错堆栈触发重跑如需重跑参照上文 Infra Failure 章节第 6 步的重跑流程。3.2 从测试输出定位失败一个实战示例关于如何从 GitHub 检查页进入完整测试输出并解读错误可参见仓库文档 Fix-failing-checks.md。其核心流程为点击失败测试的Details→ 点击View more details on flutter-dashboard→ 在页面底部找到完整测试输出链接。一份典型的测试失败输出以══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞═开头例如══╡ 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 ════════════════════════════════════════════════════════════════════════════════════════════════════解读要点Expected / Actual / Which三行对比给出了断言失败的直接原因堆栈中的(…/packages/flutter/test/widgets/async_test.dart:115:7)指明了出错测试文件与行号The test description was给出了测试用例名称。接下来只需在本地找到该测试、运行并修复即可本地运行方式可参考仓库测试文档。3.3 Flake偶发失败的处理当某个检查「随机」失败时通常先考虑先推一个新 commit / rebase 再观察有时 flake 会在重新触发检查后自行消失。根据 Ci-Best-Practices.md建议通过 rebase 合入主分支最新改动来重新触发区分 flake 与 infra 错误很多 flake 实为 infra 错误可参照 Understanding-a-LUCI-build-failure.md即本文中的 infra failure 概览来查看与上报。四、重跑Re-run / RERUN操作指南确认属于 flake 或 infra 抖动后按场景触发重跑4.1 Pre-submitPR 检查场景在 GitHub 的check run 页面点击Re-runPR 检查详情页中每个失败的检查项旁权限限制该操作仅限flutter-hackers组成员若无权限请在 Chat.md 文档提到的 Discord#hackers-infra频道请团队成员代为重跑。4.2 Post-submit合入后场景登录framework 构建仪表盘点击失败任务方块再点击RERUN权限限制受基础设施技术限制目前仅限 GooglersGoogle 内部成员操作非成员请在#hackers-infra频道请 Googler 代为重跑。注意重跑会再次消耗整台虚拟机资源。根据 Ci-Best-Practices.mdflutter/flutter 一次完整测试运行要占用 100200 台虚拟机、耗时 3060 分钟因此优先单独重跑失败的那个测试套件而不是重触发全部测试。五、从源码看 LUCI 构建任务的组织与分片理解构建任务的组织方式有助于判断「我该看哪个 builder 的失败」。5.1.ci.yaml声明式构建目标根目录 .ci.yaml 的targets列表声明了所有构建目标。一个 target 的关键字段包括字段作用仓库实例namebuilder 名称仪表盘上显示的任务名Linux framework_tests_widgetsrecipe使用的构建配方flutter/flutter_drone会委托dev/bots/test.dartrecipe: flutter/flutter_dronetimeout构建超时分钟超时即失败timeout: 60properties.shard/subshard测试分片与子分片shard: framework_tests,subshard: 3presubmit_max_attemptspre-submit 最大尝试次数自动重试 flakepresubmit_max_attempts: 2bringup/presubmit是否为试运行目标 / 是否在 pre-submit 中运行bringup: true表示暂不纳入合入门禁runIf仅当所列路径变更时才触发runIf: [dev/**, packages/**, bin/**, .ci.yaml, engine/**, DEPS]例如 .ci.yaml 中的Linux web_canvaskit_tests_3定义了shard: web_canvaskit_tests、subshard: 3并针对已知 flake 设置了presubmit_max_attempts: 2pre-submit 最多自动重试 2 次——这也是「为什么某些任务会自行转绿」的机制来源。5.2dev/bots/test.dartshard 的实际执行器dev/bots/test.dart 是 framework CI 的核心执行脚本通过SHARD/SUBSHARD环境变量选择要运行的分片例如SHARDframework_tests SUBSHARDwidgets只运行 widgets 子分片支持--dry-run列出「本来会执行」的测试便于本地核对分片范围支持--local-enginehost_debug_unopt等参数将 CI 测试切到本地自编译引擎上运行默认随机化分片内测试顺序可用--test-randomize-ordering-seedn固定随机种子复现用于暴露测试间依赖退出码语义出错时退出码为 1脚本自身异常时退出码为 255成功则以「Test successful」结束。该脚本内部将所有 shard 名称映射为对应的 runner如framework_tests→frameworkTestsRunner、web_canvaskit_tests→ Web 测试套件、analyze→analyzeRunner等这与.ci.yaml中的shard字段一一对应。5.3 本仓库的 OHOS CI 适配作为 OpenHarmony 适配版本仓库在 CI 侧增加了 OHOS 平台配置dev/bots/ohos_platform_config.dart 定义了OhosPlatformConfig当环境变量OHOS_CItrue时由 ci/scripts/run_shard_test.sh 与 ci/scripts/run_parallel_shards.sh 注入dev/bots/test.dart 会剔除skippedShards如 android 引擎测试、web 测试、customer_testing、docs等 17 个不适用于 OHOS 环境的分片并按skippedSubshards跳过framework_tests下的impeller、misc_examples等子分片按skippedTestPaths排除如build_apk_test.dart、create_test.dart等具体测试文件这意味着在本仓库OHOS 分支看到的 CI 任务集合与上游 flutter/flutter 并不完全相同排查失败时请以当前分支.ci.yaml实际启用的 target 为准。六、预防与协作建议CI 最佳实践速查结合 Ci-Best-Practices.md在实际开发中可减少失败与无效重跑This branch is out-of-date 不是总是失败该提示只是 GitHub 的自动警告不阻止合入仅当 PR 基于的 commit 本身导致测试失败、或该 commit 已过时数天时才建议 rebase优先使用auto-submit标签合入而不是手动点 merge系统会在测试全部通过后自动排队合入优先用revert标签回滚对近期合入的、导致 CI 失败的 commit使用 revert 标签可绕过大部分测试快速回滚使用前需在 PR 中注明原因优先重跑单个套件而非全量重触发全量重触发一次消耗 100200 台虚拟机新增 / 重命名 / 重分片测试的成本意识新增 target 会独占一台虚拟机 1530 分钟重分片resharding需要以bringup: true先试运行、稳定后再置为bringup: false并可能需要在所有 release candidate 分支 cherry-pick.ci.yaml整个过程可能涉及多轮 PR务必提前与team-infra团队协调。七、速查小结故障处置对照表症状仪表盘颜色常见诱因首选动作Infra Failure紫色方块网络、硬件、recipe、cipd 依赖查历史构建 → 检索team: infraissue → 提 infra bug → 判定 flake 后重跑Test Failure红色方块代码变更破坏行为、测试断言失败读错误信息与日志 → 本地复现修复 → 检索 issue / flake 记录 → 需要时重跑Flake红/紫随机出现偶发环境抖动或 infra 错误rebase 重触发观察确认后单独重跑该套件延伸阅读均在当前仓库内How to fix a PRs failing checksPR 检查失败含 tree-status、ci.yaml validation、客户测试等的系统性处理指南Flutters Build InfrastructureLUCI 机器人、recipe 编辑流程与 Android 工具链维护说明Flutters CI Best PracticesCI 资源成本与协作规范DashboardsFlutter 各类仪表盘索引与 Skia 性能看板用法Flutter Infrastructure Foundation底层测试床、虚拟机 pool 与基础设施服务清单。赞分享跨平台前端移动开发OpenHarmony【免费下载链接】flutter_flutter本仓库是 Flutter SDK 与 Flutter Engine 的 OpenHarmony 适配版本由 CPF-Flutter 团队维护。开发者可使用熟悉的 Flutter 技术栈开发 OpenHarmony 应用3.35.7 及以后的适配版本可基于本仓库源码构建支持 OpenHarmony 的 Flutter Engine。项目地址https://gitcode.com/CPF-Flutter/flutter_flutter点击查看免费下载相关推荐flutter_flutter 仓库新增测试分片Test Shard完整指南LUCI 构建配置与 OpenHarmony CI 落地实践flutter_flutter 仓库新增测试分片Test Shard完整指南LUCI 构建配置与 OpenHarmony CI 落地实践 本文基于仓库内跨平台前端移动开发OpenHarmony深入理解 Flutter 仓库 LUCI 构建失败基础设施故障与测试失败的分诊与重跑指南深入理解 Flutter 仓库 LUCI 构建失败基础设施故障与测试失败的分诊与重跑指南 在 Flutter 官方仓库中绝大多数测试已经迁移到基于 LUCI跨平台移动开发前端UI组件桌面应用OpenShift v3 部署故障排查实战指南环境配置、构建失败、镜像仓库与日志采集OpenShift v3 部署故障排查实战指南环境配置、构建失败、镜像仓库与日志采集 导读 本文以 origin 仓库中的官方排障文档 docs/debug测试云原生质量保障创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/10/15 16:53:17

Python驱动OpenSees:参数化建模与非线性分析实战指南

简介:本资源是一套面向结构工程与地震工程方向的OpenSees算例合集,重点演示Python语言在OpenSees建模、分析与后处理中的实际应用,适合具备一定编程基础、希望摆脱Tcl命令式操作、提升建模效率的工程师与研究生学习参考。压缩包共91个文件&am…

2026/10/15 16:53:17

TreeGrid树枝表控件:解决树形表格性能卡顿与层级渲染难题

简介:TreeGrid树枝表控件及Demo源码是一套面向.NET平台Windows Forms开发者的树形表格UI组件解决方案,适用于需在单个控件中同时展示层级结构与表格数据的业务场景,如组织架构管理、文件资源管理器、权限配置面板等。资源包含完整可运行的Dem…

2026/10/15 16:48:11

C# WinForms接口调试工具:HttpClient+SQLite工程化实践

简介:这是一款基于C#开发的轻量级Windows桌面接口测试工具,面向.NET初学者、Web API开发者及测试人员,用于快速验证HTTP接口功能与响应行为。工具采用WinForm框架构建图形界面,原生支持GET、POST、PUT、DELETE四种标准请求方法&am…

2026/10/15 17:43:43

ArkData RDB:文搜图标签索引切换事务回滚与读侧隔离【鸿蒙心迹】

一、相册没有坏,检索结果却在更新时短暂消失 文搜图项目做到后期,用户真正关心的已经不是“输入一句话能不能找到照片”,而是收藏过的结果能否稳定留下。设想一个本地相册:旧版标签索引能够返回十八条“海边落日”相关记录&#x…

2026/10/15 17:43:43

QThreadPool任务终止与完成通知:安全取消与跨线程回调实战

QT学习记录已经写到第三篇,这次聊一个看着简单、上手才发现坑不少的问题:如何终止 QThreadPool 里的任务,以及任务跑完以后怎么把结果“递回”给主线程。前一篇文章讲了线程池的基本用法,很多朋友留言问我“线程怎么 kill 掉”“任…

2026/10/15 17:38:42

CAN总线驱动开发实战:位定时计算、邮箱状态机与错误自愈

简介:本资源为GD32F30x系列MCU平台下的CAN总线驱动完整实现工程,面向嵌入式开发工程师、汽车电子与工业控制领域初/中级开发者,解决CAN通信底层驱动开发、调试与移植中的核心问题。压缩包含710个文件,主体为198个.o目标文件、199个…

2026/10/14 11:31:03

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/14 17:41:07

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/15 13:42:16

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/15 0:02:22

防关联浏览器哪个好?三款产品实测差异解析

新手做多店铺,最纠结的就是防关联浏览器选哪个。飞跨、网易、站斧这三款被问得最多,先给结论:要一体化省心、长期便宜,选站斧;要网易招牌和稳,选网易;预算紧做东南亚 Lazada,选飞跨。…

2026/10/15 0:02:22

影刀RPA深度实战:大模型Fine-tuning定制RPA专用Prompt与指令生成

影刀RPA深度实战:大模型Fine-tuning定制RPA专用Prompt与指令生成 一、技术背景 大模型(LLM)在通用场景下表现强大,但当我们将 GPT-4 或 Qwen 直接用于生成影刀RPA操作指令和 XPath 定位时,准确率通常只有 40%-60%。原因…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑