ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Flutter 仓库树卫生规范(Tree Hygiene):PR 落地、代码评审与回归处理的完整实践

Flutter 仓库树卫生规范(Tree Hygiene):PR 落地、代码评审与回归处理的完整实践 Flutter 仓库树卫生规范Tree HygienePR 落地、代码评审与回归处理的完整实践【免费下载链接】flutterFlutter makes it easy and fast to build beautiful apps for mobile and beyond项目地址: https://gitcode.com/GitHub_Trending/flutter41/flutter本文基于 Flutter 官方仓库的贡献文档 Tree-hygiene.md系统讲解树tree健康状态的定义、PR 从提交到落地的完整流程、测试强制要求与豁免机制、代码评审的九项检查清单、AI 辅助贡献的约束规范以及树损坏tree breakage、性能回归、跨仓库变更和破坏性变更含 API 弃用规范的处理策略并结合仓库中的分析器插件源码说明弃用语法是如何被强制校验的。读完本文你可以掌握在大型开源项目中保持主干持续绿色的工程方法论并能在 Flutter 仓库中规范地完成一次从开分支到 revert 的全流程操作。一、tl;dr树卫生的四条铁律原文档开篇即给出最核心的四条原则这是整篇规范的浓缩回归必须先回滚revert问题以后再查参见 Landing-Changes-With-Autosubmit.md。把树恢复到绿色状态的优先级最高。破坏性变更的定义会破坏flutter/tests仓库中测试的变更即为破坏性变更且必须提供迁移指南migration guide。评审响应预期普通 patch 预期在两周内获得评审如果是修复 P0 级 bug则应在当天获得评审。若超出该时间窗口应通过 Chat 渠道联系维护者。同时记住评审者是有工作与私人事务的真实的人。并发 PR 数量限制没有写权限的贡献者每个仓库最多同时保持2 个打开的非草稿 PR草稿 PR 不计入额度。应优先合并或关闭已有 PR再开新 PR。二、什么是树tree及其状态展示本文档中反复出现的 tree 一词指flutter/flutter 仓库的健康状态the health state of flutter/flutter repository。树状态展示在三个地方构建看板build dashboard每一个 PR 上称为 Tree Status 检查。这里有一个容易误解的点PR 上 tree-status 检查失败表示的是 main 分支本身有问题而不是该 PR 本身的问题。该检查会在树维护者解决问题后自动通过PR 作者无需采取任何行动社区的 tree-status 聊天频道。三、提交代码到 Flutter 仓库的完整十步流程这是原文档的主体操作脉络完整继承如下在 GitHub 上 fork 仓库并按照贡献指南配置开发环境。确保有 issue 覆盖你要做的工作。如果没有先提一个 bug/issue 描述你要解决的问题。issue 的价值在于如果 PR 最终被回滚可以重新打开 issue不至于丢失这项工作没有完整落地的记录如果某人做了一半 PR 后停止issue 也为后来接手者提供了代码指向。在 issue 上讨论设计方案参见 Design-Documents.md。可以使用 Google Doc 模板征求反馈也可以发邮件列表或在 Chat 频道讨论。团队尤其是相关 lead的支持度越高后续流程越顺畅。可以在 issue 上加proposal标签表示这里有一个待讨论的设计。隐私影响评估如果工作影响隐私面例如修改 analytics 收集方式、崩溃日志等应主动联系 Google 员工讨论变更他们会拉入专注隐私问题的工程师给出反馈。从main或尚未切换的仓库的master拉出分支并实现变更且必须保证有测试覆盖见下文测试章节。必须遵循 Style-guide-for-Flutter-repo.md 中描述的规范文件不得有行尾空格。对引擎仓库C、C 和 Objective-C 代码在提交前必须用clang-format格式化使用buildtools/OS/clang/bin/clang-format --stylefile -i。提交 PR参见 Signing-commits.md。再次强调并发限制无写权限的贡献者每个公开 Flutter 仓库最多 2 个打开的非草稿 PR草稿 PR 豁免达到上限后应聚焦于合并或关闭已有 PR。所有提交给 Google 开源项目的代码都必须遵循 Google 的 Contributor License AgreementCLA即声明贡献是原创作品。这不禁止使用编码辅助工具但提交的内容必须是贡献者本人的原创创作。获取代码评审。如果你是团队成员向你所触及领域的专家请求评审否则等待系统分配评审者见下文 Who 小节。确保 PR 通过所有 pre-commit 测试并考虑在本地运行部分 post-commit 测试如dev/devicelab目录。若有测试被破坏尤其是customer_testing测试参见下文破坏性变更章节。注意luci-flutter测试并不是在检查你的 PR它反映的是此刻树本身是否通过测试包括 post-commit 测试。当树或看板显示任何回归时只允许能改善现状的修复进入。有两个 pre-commit 测试比较特殊其失败并非由 PR 代码导致、也无法在 PR 内直接修复tree-statusmain 分支稳定性的状态指示器阻塞树的问题解决后自动通过Google Testing在 Google 内部运行不对外公开。若失败应联系 Google 员工例如 PR 评审者查看内部测试并给出建议。在一切变绿后落地需要收到所影响代码 owner或其授权委托人的 LGTM以及所有留下过评论的贡献者的 LGTM 后如果你在 flutter-hackers GitHub 组内给 PR 加上autosubmit标签bot 会在合适的时机落地该 patch如果你不在该组评审者会替你加标签。在构建看板上监控 post-commit 测试确保全部通过。若出任何问题回滚你自己的 patch 并研究问题。原文档明确要求你应该争取成为回滚自己 patch 的那个人——你会和团队中所有同样尝试回滚它的人竞速revert 操作见下文。另可参见 What-should-I-work-on.md 了解选题建议。四、测试要求强制、豁免与评审机制flutter/flutter 与 flutter/packages 仓库中的每一个变更都必须有测试建议使用代码覆盖率工具检查新代码是否全部被测试覆盖参见 Test-coverage-for-package-flutter.md。自动豁免的 PR 类型以下 PR 自动豁免必须有新测试的要求仅删除代码没有修改行或新增行用于移除功能或死代码。注意为修复 bug 而删除代码仍然需要测试豁免不适用仅影响注释含文档仅影响.github目录或.ci.yaml配置文件仅影响.md文件由自动化 botrollers生成的变更。如果评审者认为 PR 应该有测试那么无论上述豁免是否成立都需要测试。原文档特别提示添加>git fetch upstream git checkout upstream/main -b name_of_your_branch flutter update-packages # Hack away. git commit -a -m your informative commit message git push origin name_of_your_branchgit push的输出中GitHub 会提供提交 pull request 的链接。几条关键注意事项优先用git fetch而非git pullgit pull常常丢失用于定义 flutter tool 发布版本的 tag使用git fetch可以避免运行flutter update-packages时的版本不匹配更新 PR 用 rebase 而非 mergegit fetch upstream; git rebase upstream/main; git push origin your_branch_name。这样工具链才会认为你的 PR 是最新的否则它可能针对你最初分叉时的测试来测试你的代码小心对 PR 分支 force push尤其是涉及 golden image 测试时参见 Writing-a-golden-file-test-for-package-flutter.md 的 troubleshooting 部分提交信息必须详尽说明问题是什么、解决方案是什么避免在 commit message 中使用 GitHub -mention——GitHub 会把 变成通知且别人在你自己的 fork 上 rebase 你的 commit 时也会触发通知在如此规模的项目中干扰极大。需要 某人时请作为 PR 的单独评论必须完成 Google 的 Contributor License AgreementCLA在线签署仅需一分钟。六、代码评审目的、时机、对象与方法每个 PR 在 check-in 之前都必须经过代码评审包括滚依赖这样的例行操作。获得评审是指一位有 commit 权限的常规 Flutter 贡献者贡献者权限细节见 Contributor-access.md在 GitHub UI 中approved了该 PR这被称为拿到 LGTMlooks good to me。如果你自己没有 commit 权限则必须有第二位有 commit 权限的人也评审并批准你的 PR——这确保每一次提交都得到两位受信任贡献者的一致认可。Why评审的价值捕获错误即使最有经验的工程师也会犯只有评审才能发现的错误知识扩散每一行代码都被两个人读过你离开后别人仍能理解它保持诚实知道有人要读你的代码你会更少走捷径更用心地写值得骄傲的代码暴露不同的思维方式评审者大概率没有用和你相同的方式思考这个问题可能带来全新视角和更优解。When何时请求评审大 patch 要尽早请求评审不必等到能 check-in 的时候不必犹豫地请多个人评审也可以主动unsolicited评论别人的 PR但 GitHub UI 中的 approve 动作应保留给有贡献者权限的人。评审越多越好。如果两周内无人评审你的 PR可以在 Chat 频道先问#hackers说明 patch 的作用并附上链接请求评审。Who谁来评审PR 的评审者按周分配具体流程因团队而异通常与 issue triage 结合进行。代码应由你所改动代码区域的所有者tech lead或其授权委托人评审如果有任何其他人留下了评论也要等他们的 LGTM 后再落地。两周无人评审的新贡献者可以去#hackers-new频道求助。How评审的执行要点评审状态通过 GitHub 的 approval 机制管理至少一位对代码很熟悉的有 commit 权限的贡献者必须在 GitHub UI 中批准 PR 后PR 才能合并。评审者既要关注高层问题方案是否合理、代码结构是否说得通也要关注低层问题可读性、是否符合 Flutter 风格指南。原文档给出了一份编号 0–9 的评审者检查清单评审者被称为最后一道防线the last line of defense作者签署了 CLA 吗没有就请其签署并且不要看代码退后一步PR 要解决什么问题是真实存在的问题吗还有什么其他解法如何让它变得更好这是最好的 API 吗参见风格指南的 philosophy 小节。寻找状态重复state duplication、同步慢操作、纠缠complecting、全局状态、过度特化的 API、API 悬崖API cliffs与 API 海洋API oceans、没有客户视角的 API 设计这是最好的实现吗参见风格指南中good coding patterns一节。有没有 hack是否引入了更多技术债想想代码在哪些情况下可能坏掉可测吗测了吗所有代码都必须被测试。有 assert 吗鼓励大量使用断言查找缩进错误和其他琐碎的格式问题新代码的 license 标注是否正确文档是否详尽且有用寻找无用的文档、空洞的语句和面包屑检查 API 文档和注释的语法质量检查标识符命名是否符合约定。只有在完全满意之后才使用 GitHub 的 Approval 机制一句 LGTM 评论是不够的。如果感觉自己被消耗、被磨平就把评审转给别人。关于测试与责任评审者不应在 patch 没有覆盖所有受影响代码的测试时给 LGTM除非测试毫无意义。评审一个 patch 意味着与该作者共同承担这个 patch 的责任——只有在你能自信地回答关于该代码的问题时才给 LGTM。一般原则当 PR 处于确定能改善整体代码健康度的状态时即使不完美也应倾向批准评审过程中要给正向反馈以对冲评审中批评流的冲击。评审者可以表达这样更好的意见但如果不重要请用类似Shouldnt block this PR but: 的前缀让作者知道这只是可选打磨这类意见应记录为带跟踪 issue 的 TODO 注释。非贡献者无 commit 权限的评审以评论形式欢迎但请不要 approve/LGTM因为这会误导 PR 作者以为其批准具有权威性而提前合并。评论时的座右铭礼貌、感恩、优雅的专业度解释正在发生什么解释为什么给出下一步设定预期。与其让 PR 悬而未决不如关闭它Its better to close a PR than to leave it in limbo。Whatpatch 被放弃时怎么办有时贡献者无法完成落地工作。若 PR 有希望团队可能关闭它但在相关 issue 中提及让其他感兴趣的人接手。此类 issue 会打has partial patch标签。七、AI 辅助贡献指南原文档设有专门章节约束使用 AI 工具准备的 PR核心是对行为的要求而不是对工具的限制必须审查所有 AI 生成的代码在打开非草稿 PR 前以及请求对 PR 任何更新重新评审前。你对提交代码符合 Flutter 项目标准负全责——未经修改的 AI 输出通常不符合这些标准必须理解并能讨论 PR 中的代码非平凡 PR 在评审中需要讨论和迭代。如果你不理解代码就无法有意义地回应评审反馈。经验表明把评审反馈直接丢给 AI agent 然后不加批判地重新贴回其输出不会带来建设性的评审必须核实 PR 描述和评审讨论中任何 AI 生成文本的准确性AI 给错信息就是幻觉hallucination如果你把这段文本贴进 GitHub就是在向评审者歪曲你的 PR。尤其不要因为在 AI 输出里声称已处理就告诉评审者你已处理了他们的反馈——确认反馈被真正处理是你的责任。评审者视角的红旗信号由于团队时间有限而团队外生成看似合理代码的能力近乎无限评审者应对选择评审什么代码保持敏感。出现以下任一情况可考虑立即关闭 PRPR 描述用 AI 生成输出完全替换了模板且缺少至少一项明显清单内容测试、issue 链接等——一开始不遵循流程的人不太可能在评审中理解对他们的期望PR 描述与实际变更不符——贡献者没有同时审阅变更与描述到能发现这个程度说明没有遵循 AI 贡献政策PR 包含无关的 AI 生成文件例如 agent 规划用的 .md 文件——没有审阅到足以发现并删除这些文件的程度同样说明没有遵循政策。关闭 PR 时和往常一样解释原因并给出下一步。指导原则如果你在任何时候感觉自己在接收未经过滤或仅最小过滤的 AI 输出问自己如果这个 PR 不存在我会选择花时间去修复这个问题吗我会选择用一个对每个提示都要花数小时/数天才响应的 AI agent 来修复它吗除非两个问题的答案都是是否则这个评审不是对你时间的好使用。这甚至适用于已经进行到多轮评审的情况——警惕沉没成本谬误sunk cost fallacy。Philosophy为什么需要 AI 政策代码应该自己说话为什么在乎它怎么生成的——项目方总体上认同这一点所以政策聚焦于行为。这些行为无论 AI 生成还是人类生成都是问题的只是在 AI 参与时以高得多的频率出现例如提交贡献者不理解的上百行代码的 PR 一直是问题但在 AI agent 普及前很少见评审者要求修改、贡献者声称已改却实际没改——故意对评审者撒谎极罕见但不加批判地重复 AI agent 幻觉却不幸地常见无视流程的 PR 一直是问题因为标准化 PR 流程是控制评审量的关键。花了数小时/数天的贡献者比几分钟生成 PR 的贡献者更花时间去学习和遵循流程以保护自己的投入不被浪费。八、落地 patch 与树损坏Tree Breakage拿到 LGTM 之后没有 commit 权限时等待项目维护者替你提交有权限时给 PR 加autosubmit标签bot 会替你落地。任何一次 check-in 如果导致 main 分支有时称 master在任一 flutter 仓库出现回归就回滚该 check-in——即使它不是你提交的。不要尝试向前修复forward-fixpost-submit 测试失败。原文档宽慰道犯错不丢人Revert 随时发生是工程的正常部分。回滚一个 PR 的操作很简单给它加上revert标签更多细节见 Landing-Changes-With-Autosubmit.md。避免 Revert Revert Revert Revert Fix foo 式提交信息提交信息中最多只允许出现一个 Revert否则没有人能判断这次落地实际做了什么是回到之前的状态是加入新代码还是那个之前引起回归、这次修好了的争议特性只有当你确实在把大家带回到一个已知的良好状态时才使用 Revert。同时避免使用 Reland当之后要 revert 那个 revert 时直接用原始提交信息可补充后续收集到的信息重新落地 PR并附上原始 PR 与 revert PR 的链接让大家能顺藤摸瓜。九、性能回归的处理每次 check-in 后应监控性能看板。看到回归你的 commit 之后任意图表数值上升时在 PR 上评论确认该回归如果回归是预期中且是有利的权衡例如磁盘占用略增换取速度大幅提升对相关基准进行 rebaseline登录后点每张图右上角的放大镜再点自动 rebaseline 并提交如果回归不预期且可能是你 PR 的问题revert 你的 PR 并调查如果回归不预期且相当严重revert 你的 PR 并调查如果回归不预期、不严重且确定不是你 PR 的问题例如你只改了注释而分析器变慢提一个打regression、performance、P0标签的 bug自己或委托他人调查。调查应被视为高优先级你有责任在几天内确保原因被理解。Flutter 将所有意外的性能回归视为 P0直到它被控制即已知原因且要么修复在进行中要么已判定是可接受的权衡。性能回归只要被及时处理就不是问题。由 auto-roller 提交引起的性能回归回滚一个普通提交是默认行为但回滚一个 auto-roller 提交如 engine-roller会引起一些复杂情况auto-roller 提交通常包含源仓库的多个提交例如 skia-roller 包含 skia 的多个提交且可以递归叠加某些 roller 包含另一个 roller 的提交。因此一个 roller 提交实际可能包含大量叶子级提交很难定位到底是哪个叶子提交引起了回归auto-roller 会尽快再次滚入这会把 Flutter 侧 revert 掉的变更重新滚回来。要维持 revert 有效要么1暂停 auto-roller要么2在源仓库中 revert 那个叶子提交如果 auto-roller 暂停太久比如一天源仓库会积累很多提交使下一次滚入非常难管来自下一次滚入的构建失败或新性能回归很难 triage因为那次滚入包含暂停期间的所有提交。因此revert roller 提交或暂停 auto-roller 并不是引起性能回归时的默认动作。默认动作是立即提一个打performance、regression、P0标签的 issue开始调查是哪个叶子提交引起回归。定位后判断是否预期权衡是则去掉P0标签并寻找缓解手段否则在源仓库中 revert 那个叶子提交让 auto-roller 把该 revert 滚入 Flutter滚入后关闭 issue。十、跨仓库相互依赖变更如果一个特性需要同时修改框架仓库和引擎仓库你需要开两个独立的 PR。此时框架 PR 的 CI 可能因依赖尚未进入引擎 main 分支的引擎代码而失败。这种情况下先在引擎仓库落地变更等待它们滚入框架 main 分支然后 rebase 你的框架 PR。十一、破坏性变更Breaking Changes原则上Flutter 希望避免任何迫使使用 Flutter 的开发者改代码才能升级的变更参见官方兼容性政策。但有时为了更大的善是必要的我们希望 API 直观如果保持向后兼容需要把一个 API 变成若非被迫绝不会这样设计的东西那么不如干脆破坏它并把它做好。第 1 步判断你的变更是否是破坏性变更实现你想要的变更然后在不先修改测试的前提下用现有测试跑你的新代码。凡破坏即要求修改一个或多个 contributed tests 的变更即为破坏性变更。contributed tests 包括flutter/flutterPR 上customer_testing分片中的测试我们获准运行但不公开的其他测试套件例如 Google 允许我们在每次提交上运行数万个内部专有测试参见 Understanding-Google-Testing.md。此政策没有豁免因为这些测试在 CI 中运行破坏它们就会关树。即使这些测试都通过只要能想象出开发者可能受到负面影响的合理场景出于礼貌变更落地后工程师应通过邮件列表、Chat 的#announcements频道通告并给相关 issue 打c: API break标签使其进入 release notes——但这不被视为破坏性变更例如即使没有 contributed test 实际失败我们自己的测试受到显著影响时也应如此通告。第 2 步评估破坏性变更如果你的变更算破坏性变更认真考虑它是否真的必要且有收益。考虑写一份设计文档与代码评审者讨论并在 Chat 上提出。第 3 步准备你的变更如果认定变更价值足够调整 PR 使其以opt-in选择性开启方式引入新功能、API、行为变化从而避免立即破坏。例如不要直接用一个 widget 替换另一个而是引入新 widget 并引导用户弃用旧的不要直接改变某参数的处理顺序而是提供一个 flag 来选择顺序。当以临时 opt-in 方式改变一个 API 的语义时需要三阶段变更加入新 API 和 opt-in → 移除旧 API → 移除 opt-in。尽量避免四阶段弃用加入新 API 并起临时名、弃用旧 API → 移除旧 API → 把新 API 改名回旧名并弃用临时名 → 移除临时名因为它带来大量 churn 并会激怒开发者。变更和变更文档要分阶段提交。通常是两个或更多 PR外加修复第 1 步中被破坏测试的 PR以及作为 Website 仓库 PR 的迁移指南。如果可能包含 flutter fix 以帮助用户迁移并在迁移指南中说明该变更是否被 flutter fix 支持编写 fix 参见 Data-driven-Fixes.md。使用官方破坏性变更迁移指南模板创建描述该变更的迁移指南遵循模板中注释里的所有说明。此时不要落地迁移指南——你还需要在最后一步落地前更新它。第 4 步落地你的变更准备好、收到反馈、迭代了设计与迁移指南之后落地初始变更并开始迁移客户。此时仍不要落地迁移指南。等所有客户迁移完成后落地最终变更多阶段推出时这里可能有多轮迭代。此过程中每个单独的 PR 都不破坏任何测试因此不应阻塞任何 autoroller。第 5 步记录变更包括清晰的迁移代码文档一切落地之后根据你迁移所有人的实际经验更新迁移指南更新指南上的时间线并推送到 flutter.dev 网站记得同时更新该目录的 index把副本发到通告邮件列表在 Chat 的#announcements频道通知给相关 issue 加c: API break标签使其出现在即将发布的 Release notes 中。弃用Deprecations规范旧 API 可以在此流程中被标记为弃用。弃用不是逃避破坏性变更的手段——应把弃用 API 等同于移除 API 来考虑因为部分客户包括我们自己把使用弃用 API 视为禁忌会触发构建失败。弃用注释必须匹配如下模式Deprecated( Call prepareFrame followed by owner.requestVisualUpdate() instead. This will enable an improvement to performance in a future version of Flutter. This feature was deprecated after v2.9.0-0.1.pre. )即三段式Deprecated( [迁移方法描述] [为什么破坏该 API 的简短动机] This feature was deprecated after v[弃用时的 beta 版本]. )使用这种标准格式可以让我们写脚本检测并移除所有弃用 API。仓库中确实有一个测试验证该语法——具体实现就在分析器插件 deprecation_syntax.dart 中。从源码看该规则DeprecationSyntax以 ERROR 级别检查弃用消息必须是相邻字符串拼接AdjacentStrings形式最后一个字符串字面量必须匹配正则This feature was deprecated after v(?major\d)\.(?minor\d)\.(?patch\d)(?build-\d\.\d\.pre)?\.$即版本号必须以v开头并以句点结尾版本号必须是beta 分支版本规则特别处理了3.1.0这个特例可不带 build 后缀其余满足major 1或major 1 且 minor 20的版本号必须带-\d\.\d.pre的 build 后缀描述部分每条字符串必须用单引号、以大写字母开头、以.、?或!结尾不符合时可通过// flutter_ignore: deprecation_syntax或带 issue 链接的 legacy 注释豁免。该规则的测试用例 deprecation.dart 覆盖了各种合法与非法场景错误的版本号、缺 version 行、双引号字符串、大小写错误等并由 deprecation_syntax_test.dart 驱动验证。最新 beta 版本号可查 flutter.dev 的安装归档页。在框架中加入弃用通知时应随变更附带一个 flutter fix帮助用户尽可能容易地迁移如果无法为新 API 编写 fix请向 dart-lang/sdk 提 issue 并在变更中链接。一个实战陷阱弃用某个特性时你自己默认不会被通知 Flutter 代码自身使用该弃用特性的位置——因为根 analysis_options_common.yaml 中有这样一段配置analyzer: errors: # allow deprecated members (we do this because otherwise we have to annotate # every member in every test, assert, etc, when we or the Dart SDK deprecates # something) deprecated_member_use: ignore deprecated_member_use_from_same_package: ignore文档给出的找法是把声明改名看编译器在哪里抱怨不能直接注释掉 ignore因为它还压着成百上千个其他警告……。最后框架中目前不计划移除弃用 API历史上曾按固定时间移除现在没有在实践中执行。若将来恢复移除会跨多个渠道通告邮件列表、Discord 等见 Chat.md提前宣布。十二、跳过的测试Skipped Tests测试可以用test()、group()和testWidgets()的skip参数跳过但应保持最少且只允许以下两个理由理由一flaky 测试的临时跳过——为了在修复开发期间保持树绿色。必须提一个跟踪 issue 以确保后续有人移除 skip该 issue 打skip-test标签并在参数同一行的注释中包含链接skip: true, // https://github.com/flutter/flutter/issues/XXXXX理由二设计上在特定条件下无意义的测试——例如只测试某个特定平台/环境可用特性的测试。在skip参数同行加[intended]标记和简短说明skip: isBrowser, // [intended] There are no default transitions to test on the web.仓库的 bot 代码本身大量使用这种约定例如 check_examples_cross_imports_test.dart 中就有skip: hasNoCrossImports, // [intended]: Nothing to log if there are no known imports这样的用例。如果分析器脚本看到一个skip而它的注释既没有 issue 链接也没有[intended]标记就会报错并使该检查失败。小结Tree-hygiene 规范体现的核心工程哲学是主干绿色压倒一切回归先 revert 再调查、双信任人评审机制两位有 commit 权限者共同批准、测试是默认义务豁免是例外且受审计、破坏必须分阶段并全程留痕opt-in 三阶段 迁移指南 通告以及对自动化流程auto-roller、autosubmit bot、deprecation 语法检查插件的敬畏与适配。上述每一条都能在仓库中找到对应的制度落点从 analysis_options_common.yaml 的分析器配置到 dev/flutter_analyzer_plugin 中强制弃用语法的插件规则再到dev/bots下的各类检查脚本——规范文本与代码实现互为印证共同维持着这个大型仓库的持续健康。【免费下载链接】flutterFlutter makes it easy and fast to build beautiful apps for mobile and beyond项目地址: https://gitcode.com/GitHub_Trending/flutter41/flutter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表