trac 经验谈之(3)工作流篇
Trac 经验谈之(2)杂谈篇补遗
Trac 经验谈之(3)工作流篇
Trac 经验谈之(4)报表篇
Trac 经验谈之(5)插件篇
Trac 经验谈之(6 完)插件篇补遗
=================
trac 经验谈之(3)工作流篇
赖勇浩(http://laiyonghao.com)
Trac 的工作流 ticket-workflow 其实是一个状态图。一个 ticket 从出生到消亡,经历许多状态,相关人员的工作(Action)推动着这些状态变化。在早期,Trac 的 ticket-workflow 是很简陋的和固定的(见上图),显然,这并不能普适广大用户的需求,所以自 0.11 版本开始,Trac 抛弃了之前固定的 ticket-workflow,开始使用可以由用户自定义的 ConfigurableTicketWorkflow,至此,针对 ticket 的工作流可以由插件控制。下面我们先回顾一下 v0.11 新的默认工作流,并从中了解一些基本概念,如状态(state),动作(action)等:
如上图,每一个节点称为状态(state),而连接结点的有向边称为动作(action),由状态和动作可以构建出状态转换表。上图共有 new、assigned、accepted、reopened 和 closed 等共 5 种状态,每一条 Ticket 必定处于这些状态之一。当一个动作(action),如 reassign、accept、resolve 或 reopen 作用在其上时,它的状态就改变为下一个状态。通常而言,不同的状态意味着这个 ticket 正在由不同的团队负责完成其中的一部分工作,并将在这个团队完全其所负责的这部分工作后,转换到下一状态。关于此点一一说明如下:
- new:新建一个 ticket,所有新建的 ticket 都处于这个状态,一般来说,应该任何人都可以新建 ticket;
- assigned:当 ticket 的 owner 发生改变,而 owner 又未 accept 时处于此状态;意味着这条 ticket 还没有人负责;
- accepted:ticket 已经被接受;意味着开发团队正在开发功能或修正缺陷;
- closed:ticket 被关闭;意味着 QA 团队正在测试或已经通过测试
- reopened:ticket 被重开,意味着 QA 团队发现功能未开发完成或缺陷未修复,重新指定 owner 负责跟进。
我们团队刚开始时使用默认的 basic-workflow,后来发现有几点不足:
- reopened 状态让美术、策划很难理解,容易产生困惑,而且配置的时候多一个状态,麻烦不少;
- 缺乏一个专门用以 QA 团队的状态,看到 closed 的 ticket 无法确定这个功能是否已经通过验证或缺陷修复是否已经通过回归测试。
针对上述问题,我们通过编辑 trac.ini 文件的 ticket-workflow 一节,定制了自己的工作流,我们工作流的状态转换图如下:
通过上图,可以看到工作流的主线 new->accepted->resolved->closed,比上面的版本都要明晰。我们去掉了 reopened 状态,代之以 assigned 状态,因为这两个状态本来就很相似,当 reopen 一个 closed ticket 时,需要指定一个 owner,并进入到 assigned 状态,其中关键配置是:
reopen.operations = del_resolution,set_owner此外,我们增加了一个 resolved 状态,它表示开发团队认为该功能已经开发完成或缺陷已经修复,并交由 QA 团队跟进测试,其中的关键配置是
resolve.set_owner = tester1, tester2它把能够接受 resovled 状态的 ticket 的 owner 限定为测试人员,其中 tester1 和 tester2 是测试人员的用户名。这个 (action).set_owner 设置项是一个不传之秘,一般人都不知道咧。
只有 resovled 的 ticket 才能转换到 closed,这个动作叫 test,明确地把 QA 的重要性体现了出来,也体现了从提出问题->解决问题->验证方案->结案记录的完备流程。
最后,给出我们的工作流的完整配置:
[ticket-workflow] leave = * -> * leave.default = 1 leave.operations = leave_status accept = new,assigned -> accepted accept.operations = set_owner_to_self accept.permissions = TICKET_MODIFY reassign = new,assigned,accepted,resolved -> assigned reassign.operations = set_owner reassign.permissions = TICKET_MODIFY reopen = closed -> assigned reopen.operations = del_resolution,set_owner reopen.permissions = TICKET_CREATE resolve = assigned,accepted,resolved -> resolved resolve.operations = set_owner resolve.permissions = TICKET_MODIFY resolve.set_owner = tester1, tester2 test = resolved -> closed test.operations = set_resolution test.permissions = TICKET_MODIFY
to be continued...