本文永久链接 – https://tonybai.com/2022/08/12/practices-of-multi-label-based-issue-driven-software-development

软件吞噬世界,开源吞噬软件!基于工单跟踪系统(issue tracking system)的issue driven开发的模式不仅对开源系统的开发过程有着重要影响,在商业软件开发领域,越来越多的公司和组织也在使用issue-driven的开发方式。

对于这里提到的issue(工单),我们不能向过去那样仅仅将其理解为bug,那样就太过狭义且过时了。如今的issue承载的信息“包罗万象”,凡是与project/repo相关的事情都通过issue形式提出,包括新特性、bug、改善、技术提案、任务、讨论等等。

有了issue tracking system后,我们将面临一个问题,那就是如何组织issue使得基于issue-driven的软件开发过程更加科学有效率呢?为此我拜读了几篇有关issue组织和管理的Empirical study(实证研究)的paper(阅读地址见“参考资料”一节),这里综合了一下paper的结论:

  • 使用标签(label)有利于软件项目中问题的解决;
  • 使用多标签(multiple label)功能的项目能更有效地管理他们的issue。

关键词get到了么?没错,就是“多标签”。使用多标签对issue进行组织可以更有效的对issue进行管理。那么设置哪些标签,又如何给issue打多个标签呢?关于这些问题,paper没有给出答案,还是需要我们自行实践探索。

本文我就给出一种基于多label的issue驱动的软件开发实践的思路,供各位童鞋参考,但注意:这不是最佳实践哦,仅是一种可行的(甚至还不成熟的)实践而已,各位读者也可以在该实践的基础上自行扩展。


1. label管理,分类先行


Go项目采用多标签组织issue的示意图

issue tracking system大多内置一套label供你直接选择使用,比如下面就是github和gitlab提供的默认issue labels:

  • github的默认issue label集合
- bug
- enhancement
- document
- duplicate
- good first issue
- help wanted
- invalid
- question
- wontfix
  • gitlab的默认issue label集合
- bug
- enhancement
- documentation
- suggestion
- discussion
- support
- confirmed
- critical

同时issue tracking system也支持自定义label,但我们不能无脑地定义新label,要考虑label的功用,对其进行科学分类(categorizezation)。

我们分析一下上面github和gitlab提供的默认labels,多数用于表示issue的类别(category),因此我们首先要定义一组能表示issue类别的labels,这个可综合上述的默认label集合,并结合日常工作上下文的需要来定制。

比如,我这里就定制了如下表示issue类别(category)的label集合:

- bug
- feature
- task
- proposal
- enhancement
- suggestion
- discussion

这些label是整个issue-driven开发的基础,每个新创建的issue必然要首先被赋予(assign)一个代表类别的label,秉着最常用的label要尽量的短的原则,我们用单个单词来表示每个label,没有使用前缀字符串。

接下来,我们再来定义几组label集合:

  • 代表工作流(workflow)的label集合
- workflow/confirmed
- workflow/accepted
- workflow/need-investigation
- workflow/wait-for-info
- workflow/need-proposal
- workflow/need-review
- workflow/declined
- workflow/blocked
- workflow/wontfix
- workflow/duplicate

之所以要带上workflow前缀,是为了减少开发人员在选择label时考虑label究竟是哪一类集合的负担,通过前缀一目了然。

  • 代表优先级(priority)的label集合
- priority/critical
- priority/release-blocker
- priority/security
- priority/urgent
  • 代表涉及组件(component)的label集合
- component/proto
- component/tracing
- component/logging
- component/metrics
- component/api
... ...

在定义不同功用的label集合时,务必注意以下几点:

  • 一般不需要定制诸如todo这样的label

哪个放入issue系统中的新建issue不是要todo的,再定义一个todo label有些多此一举的感觉。另外很多自带看板功能的代码仓库管理工具,在issue被纳入某个milestone后,会自动将你新创建的issue列入到该milestone看板中的todo列中。

  • issue的版本信息可用milestone来标定

我们一般无需创建持有版本信息的label,可以利用milestone(里程碑)标识issue的版本属性。

  • 自上而下定义label集合

对于同一个组织而言,工作流的一致性很重要,这样就需要我们自上而下的定义label集合,而不是每个project都定义自己的label集合。

如果你使用的是gitlab(据调查,国内多数公司使用的都是gitlab),由于gitlab中group支持label定义,我们可以在顶层group中定义一套label集合,这样其下面的subgroup和project repo都可以“继承”这套label集合了。

如果project有个性化的label需求,project可以在统一的label集合的基础上再自定义自己的label,这样就会避免大量重复定义,也保持了label集合的一致性,为后续workflow运转奠定基础。

定义完这几类issue后,我们再来看看issue从创建到驱动开发“运转”起来的过程是什么样的。

2. 基于多label issue驱动的工作流


基于多label issue驱动的工作流的示意图

1) 规划和创建milestone

无论采用哪种开发过程(瀑布、迭代还是敏捷),最终都是要输出成果物,我们通常会将每个版本成果物输出作为一个milestone,因此在创建issue之前,我们首先会规划和创建milestone,而milestone本身也内含了issue的版本属性

如果你使用的是gitlab,你既可以在group这一层设置milestone,也可以在某个具体的project上设置milestone。

如果你的输出输一个包含多个服务的产品,那么在group/subgroup这一层设置milestone可以统一产品的发布版本。

此外,我们可以在适当层级上建立backlog这个长期的milestone用于将那些尚未分配版本的issue收集起来。

一旦如此规划和创建好milestone,leader后续就可以面向milestone进行管理了。接下来我们就可以来创建issue了。

2) 创建issue,选择category label

我们的workflow要求:每当开发人员、测试人员、leader或相关人员创建一个issue后,务必要选择一个category label

- bug:导致产品或服务未按预期工作的问题
- feature:新增的功能特性或非功能特性
- enhancement:已有特性机制的增强与优化
- task:与产品/服务相关的任务,可能不需要编码
- discussion:发起一次针对特定话题的讨论,需要团队member积极参与
- suggestion:针对产品/服务的建议,需要团队member参与review
- proposal:针对产品某功能特性或非功能特性的技术提案,issue中通过markdown语法填写proposal的提案内容,供大家review

为issue选择一个category label是后续推动workflow流动起来的前提与基础。

3) 选择版本milestone

为刚刚创建的issue选择一个milestone。

对于bug、feature、enhancement类的issue,选择在哪个版本(milestone)里完成。而尚未确定的issue,可以放入backlog milestone,待后续重新放入版本milestone

对于其他category类型的issue,比如proposal、discussion,可以先无需选择版本milestone,可先放入backlog。

4) 选择workflow类别的label

接下来,我们就需要根据issue的类别,为其赋予适当的workflow label,让issue进入工作流中。

  • 对于bug类型的issue

对于bug类issue,如果不明确是否为bug或证据不足,可以选择workflow/need-investigation或workflow/wait-for-info;

在调查之后,如果确定是bug,那么需要有开发人员或leader去掉上面的workflow标签,然后重新赋予workflow/confirmed标签。只有经过confirmed的issue,才可以纳入版本milestone跟踪起来,没有confirmed的bug issue,可放入backlog milestone中等待确认;

如果是重复的issue,可以选择workflow/duplicate,然后我们可以close这个duplicate issue;

对于非bug,或经评估后无需fix的issue,可以选择workflow/wontfix,然后close issue。

  • 对于feature或enhancement类的issue

如果需要做技术调研,可以选择workflow/need-investigation;

如果需要技术提案/设计实现方案,可选择workflow/need-proposal;

如果需要issue提出者给出更多信息,可以选择workflow/wait-for-info;

如果接受feature或enhancement类issue,可以选择workflow/accepted,然后确认其处于正确的版本milestone中。

  • 对于proposal类issue

对于proposal类issue,团队需要决策是否接受该提案,初期可以选择workflow/need-review,在经过review后可以选择是否接受,如果接受,选择workflow/accepted,一旦accepted,便可以新选择纳入哪个milestone中落地。如果不接受,那么选择workflow/declined(拒绝),然后close issue。

最后,对于因各种原因暂时无法继续下去的issue,可以选择workflow/blocked。等导致阻塞的问题解除后,再为该issue重新选择workflow label。

5) 选择issue优先级(可选)

issue通常无需选择优先级。只要纳入版本milestone,在milestone范围内都是需要完成的。

不过,我们也自定义了一些用于需要“着重”关注的优先级label,供灵活使用。

- critical - 关键issue, milestone内必须要完成的
- release-blocker - 通常针对bug类issue,如果该issue不解决,milestone无法按时完成和发布
- security - 安全类issue,提升issue优先级
- urgent - 紧急突发类issue,可以用于patch补丁的issue

6) 选择component(可选)

为issue选择component类标签更多是为了统计和过滤使用。这里的logging、tracing、metrics等仅做举例之用,大家可以根据自己的产品/project上下文定义必要的component标签。

7) 基于workflow标签驱动

当我们完成一轮label赋值后,开发人员便依据issue在workflow中所处状态开始后续工作,一旦工作告一段落,会改变issue的workflow标签,直到issue完成被close。

3. 小结

本文提出了一种基于多label issue驱动的软件开发的实践思路,通过这种思路,可以让一个团队围绕issue tracing system有机的运转起来。

如果issue众多,人工管理不便的情况下,还可以引入issue bot按设定好的规则对issue的状态做自动维护以及相应的提醒,这个我后续如有空闲会继续说。

4. 参考资料

  • 《如何使用Issue管理软件项目》 – https://www.ruanyifeng.com/blog/2017/08/issue.html
  • 《The Complete Guide to Issue Tracking Best Practices》 – https://kissflow.com/issue-tracking/issue-tracking-best-practices-guide/
  • 《Exploring the use of labels to categorize issues in Open-Source Software projects》- https://ieeexplore.ieee.org/document/7081875
  • 《An Empirical Study on Using Multi-Labels for Issues in GitHub》- https://ieeexplore.ieee.org/abstract/document/9550775

“Gopher部落”知识星球旨在打造一个精品Go学习和进阶社群!高品质首发Go技术文章,“三天”首发阅读权,每年两期Go语言发展现状分析,每天提前1小时阅读到新鲜的Gopher日报,网课、技术专栏、图书内容前瞻,六小时内必答保证等满足你关于Go语言生态的所有需求!2022年,Gopher部落全面改版,将持续分享Go语言与Go应用领域的知识、技巧与实践,并增加诸多互动形式。欢迎大家加入!

img{512x368}
img{512x368}

img{512x368}
img{512x368}

我爱发短信:企业级短信平台定制开发专家 https://51smspush.com/。smspush : 可部署在企业内部的定制化短信平台,三网覆盖,不惧大并发接入,可定制扩展; 短信内容你来定,不再受约束, 接口丰富,支持长短信,签名可选。2020年4月8日,中国三大电信运营商联合发布《5G消息白皮书》,51短信平台也会全新升级到“51商用消息平台”,全面支持5G RCS消息。

著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。

Gopher Daily(Gopher每日新闻)归档仓库 – https://github.com/bigwhite/gopherdaily

我的联系方式:

  • 微博:https://weibo.com/bigwhite20xx
  • 博客:tonybai.com
  • github: https://github.com/bigwhite

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

© 2022, bigwhite. 版权所有.

No related posts.