查看原文
其他

GitHub 用对了吗?Flutter 团队分享如何管理大型开源项目

Flutter 谷歌开发者 2021-08-05
作者 / Ray Rischpater, Technical Program Manager, Google Flutter team

我们很荣幸能从 Flutter 开发者那里收到大量的积极反馈。作为 GitHub 上活跃度非常高的 repo 之一,开发者们提交的海量 issue 是我们面临的独特挑战。我们有着独到的理念和方法来应对数量庞大的 issue 和随着项目不断发展而来的变化,以及一些实用技巧发挥提交 issue 的最大价值。希望这些分享对您有所帮助。


有时,开发者会尝试使用公开记录的 issue 总数来衡量项目的整体质量。我们认为该数字与项目运行状况之间的相关性很低。我们希望通过本文与大家共同探讨,为什么 issue 越多越可能意味着和项目的质量和受欢迎程度反而更高。


最后,我们还想分享最近几个月内实施的一些具体变更,包括: 积极清理积压的 issue,实现 (并保持) 未分配问题的零错误反弹,以及采用新的优先级排序方案以更加贴近开发者的实际需求。



Flutter 团队如何使用 GitHub


在当今的软件开发领域,开发团队积累由团队成员和用户提交的 issue 已是一种普遍情况: 所谓积累 (backlog),就是开发团队所面临的 bug、功能需求和技术负债的总和。Flutter 也不例外: 我们使用 GitHub 管理积累的 issue。不论是 bug、还是新功能的想法,或介于两者之间的内容,我们都会将其作为 issue 记录在 GitHub 的 issue 页中。


  • Flutter 在 GitHub 的 issue 页
    https://github.com/flutter/flutter/issues


每个 issue 都来自您或 Flutter 的其他贡献者。贡献者和用户在 flutter/flutter issue 追踪页中提交有关 Flutter 或 Flutter API 文档的问题,并在 flutter/website issue 追踪页中提交有关 Flutter 网站 (flutter.dev) 的问题。


  • flutter/flutter issue 追踪页
    https://github.com/flutter/flutter/issues
  • flutter/website issue 追踪页
    https://github.com/flutter/website/issues


庞大的 issue 数量源于我们在 GitHub 上遵循的以下三条管理思路:

  • 代码仓库的 issue 是完全开放的: 核心工程和产品团队以及整个 Flutter 社区会将所有功能需求、bug 和可能的工作计划都提交到这个开放的 repo 中;

  • 我们不急于关闭 issue,即便是短期内不打算处理的 issue: 我们希望公开所有累积的工作,以便将来的任何贡献者都可以着手处理其感兴趣的功能,并查看前期的讨论内容;

  • 除涉及开发者工具链和网站的问题外,我们只使用一个 repo 收集所有的 issue。Android、iOS、Windows、Web、macOS 和 Linux,框架和引擎,API 文档和插件相关问题全部都记录在 flutter/flutter repo 中。



Flutter 的优先级划分流程


Flutter/flutter repo 中的 issue 由一名团队成员划分优先级: 可以是志愿者,或是 Nevercode 团队中一直协助分级的成员,或是 Google 员工 (或其他公司员工)。为便于分级,我们为 issue 设置了尽可能丰富的标签。


  • Nevercode
    https://blog.codemagic.io/flutter-and-codemagic-join-forces-on-github/


一些标签会需要 issue 进行二次分级。例如,engine 标签会将 issue 转发到引擎团队进行二次分级。其他标签可表示另外的特性,例如这个 issue 是功能需求还是改进点,来提高团队处理的速度 (在我撰写本文时,该标签下已包含超过 500 个 issue)。


  • Engine 标签
    https://github.com/flutter/flutter/labels/engine
  • Team 标签
    https://github.com/flutter/flutter/labels/team


在一次和二次分级之间,我们还为针对代码库或 API 文档提交的 issue 分配了优先级标签。与其他 bug 追踪页类似,我们使用从 P0 到 P6 的优先级排序方案:
  • P0 标签表示必须立即解决的最高优先级问题,例如阻断了构建或严重的性能回退。

    https://github.com/flutter/flutter/labels/P0

  • P1 标签表示该问题需要及时关注,例如,大多数用户使用的主要功能出现故障,或者妨碍到战略合作伙伴使用 Flutter 的问题。我们会计划在当前里程碑内解决或改善 P1 错误。

    https://github.com/flutter/flutter/labels/P1

  • P2 标签表示影响我们大部分用户的主要功能或问题。与 P1 问题一样,我们计划在当前里程碑内解决或改善这些问题。

    https://github.com/flutter/flutter/labels/P2

  • P3 标签表示该 issue 位于我们发布产品的时间表内,且位于工作列表顶部。我们正在积极处理的许多 issue 都带有这个标签,并且大多都已经有确定发布时间的里程碑。

    https://github.com/flutter/flutter/labels/P3

  • P4 标签表示我们同意该 issue 的重要性,但不在工作列表的顶部。这是默认的 issue 级别。

    https://github.com/flutter/flutter/labels/P4

  • P5 标签表示我们认为该 issue 有效但非重要。这是新功能请求的默认级别。

    https://github.com/flutter/flutter/labels/P5

  • P6 标签表示该 issue 有效但不大可能被处理,但我们保持其开放状态,以便其他贡献者解决该问题。
    https://github.com/flutter/flutter/labels/P6


这是一种相对较新的方案,取代了我们之前的三轴体系: 承诺在下个里程碑解决、"customer:" 和 "severe:" 标签。在建立这个方案的过程中,我们根据承诺的发布里程碑和其他标签为大量 issue 自动确定了优先级。



通过 bug 数量衡量项目质量


Flutter 使用 GitHub 完全开放地记录 bug 和功能需求的 issue,因此 issue 的数量与产品质量之间没有直接关联。其他开源项目例如 (Chromium 和 TensorFlow) 也完全在开放的状态下开发,issue 量同样很大。如果说这种数量代表什么,它恰恰说明该项目是活跃且充满生机的,因为用户只有参与使用该产品后才能发现 bug 和需要改进的内容。


  • Chromium
    https://bugs.chromium.org/p/chromium/issues/list
  • TensorFlow
    https://github.com/tensorflow/tensorflow/issues


而项目之间很难进行横向比较。某些项目会主动关闭不打算解决的 issue;有些项目会隐藏 issue 数据,还有一些项目则针对不同类型的 issue 使用不同的项目。如前所述,我们在同一个 repo 内跟踪功能改善需求和 bug。我们还会针对工具、Android、iOS、第一方插件等使用同一个 repo。


更适合用来衡量开源项目运行状况的一项指标是查看已关闭的 issue 数量与当前开放的 issue 数量的对比情况。截至撰写本文时 (2020 年 7 月上旬),我们有 7,757 个开放的 issue 和 32,485 个已关闭的 issue。尽管最近几个月的完结率有所下降,但总体在过去的一年中持续提高:

去年 12 月完结率下降是由于这段时间 Google 内部和许多其他的贡献者都在休假。总的来说,每年的平均月结 issue 数为 1,314,而且您会发现最近半年的平均月结数高出许多,高达每月 1,604 个。



了解未结 issue


为了更好地了解我们面临的 issue 类型,Flutter 团队随机抽样了 1,200 个未结 issue,并对其进行了重新分级。我们了解到:
  • 提交的 issue 中有 32% 来自项目的核心贡献者。其中许多涉及未来的工作项目,例如功能、改进产品的方法,或者改进我们团队的工具和基础架构的方法,从而帮助我们自己提高开发速度;
  • Flutter 的贡献者平均提交了 7.4 个 bug,Flutter 所有提交过 bug 的用户则平均提交了 1.2 个 bug;
  • 在我们抽样的 issue 中,约有 25% 是明显无法采取行动的支持请求,或已不再有效的请求 (即随后的工作已解决了该问题或产品的转型使得该问题已经过时),我们可以关闭这些 issue。

无论是最近提交的 issue 还是较早的 issue,我们都将继续和 Nevercode 一起进行积极的清理。他们在以下几个方面让我们获益良多:
  • 主动为 issue 创建可复现的代码,以帮助其他工程师寻找解决 Flutter 内真实 bug 的方法;
  • 去除重复 bug,并在交叉链接后关闭重复项目;
  • 关闭不可复现的 bug 以及支持请求 (这些请求应定向到 Flutter 用户社区中所列出的渠道之一);
  • 要求针对描述不明确的 issue 提供更多信息,并关闭无法采取行动的 issue;
  • 在时间允许的情况下,帮助我们有选择性地处理积压的 issue,选择方法是回答这几个问题: 该 issue 是否仍存在?该 issue 是否可复现?该 issue 是否和既有其他 issue 重复?

  • Flutter 用户社区
    https://flutter.cn/community


我们和 Nevercode 一起,发现大家提交的 issue 有一个有意思的数据: 在过去的两个月中,提交的 issue 中有 55% 不符合我们的标准: 要么是支持请求,要么没有可复现的案例。


对于较早的 issue,Nevercode 团队发现无效或重复的 issue 较少,这很可能是由于幸存者偏差造成的,也就是说先前在分级中留存下来的 issue 通常不会是无效或重复的 issue。但是在他们的样本中,有 18% 的 issue 是无效的 (属于支持请求或无法采取行动),另有 15% 是重复 issue。最多的一部分 issue——占比高达 50%——其实反映了随后已被解决的 issue,这表明随着功能的新增和 bug 的修复,旧有的 issue 可以得到更好的解决。



Issue 优先级排序


截至撰写本文时 (2020 年 7 月上旬),P0-P2 issue 细分如下:

上图显示我们正在紧急处理的 issue 数量处于合理的状态。正如大家对热门开源项目的预期,我们的 issue 数据库中也包含很多其他的反馈意见。以下是 P3-P6 issue 的细分:

团队在处理优先级较高的 P0-P2 issue 时,也在积极处理多项 P3 issue。


我们仍留有历史积压的已分级但非优先处理的 issue。其中,我们认为大多数 issue 可以分类为 P5 或 P6,因为作为 Nevercode 所做的分级工作的一部分,值得立即关注的 issue 已得到了升级。


一个 issue 进入到二次分级,并不意味着核心工程团队就有足够的精力来处理它。在二次分级中,我们将基于以下标准来确定如何处理该 issue,包括:
  • 还有哪些其他工作必须处理?
  • 该 issue 的严重程度如何?
  • 该 issue 影响到多少人?
  • 它是针对于特定用户的 issue 吗?
  • 处理该 issue 对发布日程和架构有多大影响?

有关我们如何完成这项工作的详细信息,您可以查看我们之前发布的文章。


  • 文章: Issue、Bug 和 Backlogs
    https://medium.com/flutter/https-medium-com-flutter-issues-bugs-and-backlogs-5fb3adab5e25


您能提供怎样的帮助


GitHub 上的 Flutter issue 数据库不仅是面向团队的,它也面向整个社区,因此我们都需要为其建设出一份力。我们可以通过如下工作来帮助确保 issue 数据库中 issue 的质量:
  • 请勿提交支持请求。应该通过我们在 Flutter 用户社区中说明的渠道提交支持请求。我们会主动关闭在 GitHub 中提出的支持请求;
  • 在合适的数据库中提交 issue: 在 flutter/flutter issue 追踪页提交 Flutter bug、API 文档 bug 和功能请求,在 flutter/website issue 追踪页提交有关 Flutter 网站或 codelabs 的反馈;
  • 提交 issue 时,请搜索以查看您遇到的问题是否已经存在。如已存在,可以为其投票和适当评论。在针对未来工作计划进行 issue 排序时,开发团队会将投票量作为衡量关注度的指标;
  • 交叉链接非常实用!在提交新 issue 或对遇到的 issue 进行投票时,请和相关的 issue 进行交叉链接。就像投票一样,团队在调查中也会使用交叉链接,您很可能会看到其他人错过的交联关系;
  • 请确保您提交的 bug 包含团队复现该错误所需的所有内容。对于开发团队来说,最小复现代码对于快速找到 bug 的根源至关重要。请明确表述某一功能的重要性,这能使开发团队更快地确定工作的优先级;
  • 请考虑帮助开发团队执行分级工作。发现 bug 后,如果您有时间复现它的话,请尝试在最新稳定版和 master 版本中复现您所发现的问题,并告知我们。如果您发现了相关的 issue,请对相关的 issue 进行交叉链接。想要编写代码的话,请提交能展现 issue 的单元测试的 pull request,如果提交的是带有修复方案的单元测试就更好了。我们欢迎您在 issue 管理方面提供帮助,如果您有意提供支持,请参阅我们的贡献指南以获取有关如何参与我们的分级流程的详细信息。


  • Flutter 用户社区
    https://flutter.cn/community 
  • flutter/flutter issue 追踪页
    https://github.com/flutter/flutter/issues
  • flutter/website issue 追踪页
    https://github.com/flutter/website/issues
  • 贡献指南
    https://github.com/flutter/flutter/blob/master/CONTRIBUTING.md


最后,我谨代表 Flutter 的开发者们,由衷感谢大家的持续支持,我们将继续帮助您打造精美、高性能的应用!




推荐阅读






 点击屏末 | 阅读原文 | 访问 Flutter 开发者社区中文资源



    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存