研发管理(三)从实际出发优化jira使用

前面两篇文章我们详细介绍了团队现有的研发模式,引出我们为何选择jira,同时对jira基础内容做了详细的讲解。并且通过jira基本实现了之前在墙上的看版模式,使得问题修改实时在线化,问题状态变更能够实时邮件通知。现在就让我们来梳理下使用一段时间遇到的问题,以及我们是如何解决这些问题的。

首先介绍下在实施过程中我们所遇到的问题如下:

1.字段必填:使不能设置成必填字段的字段变为必填字段,避免字段缺失。
2.子任务字段复用:让子任务创建时直接复用主任务的字段,减少重复填写。
3.快捷筛选项:让产品同学能够快速筛选到自己的提出的需求并查看进展。
4.早会看版:如何让早会看版更简洁,并体现所开发的内容。
5.工作日志弹框:让开发同学在拖动卡片状态时自动弹出工作日志登记弹框。
6.故事状态同步:当子任务拖动状态变更时,自动同步主任务状态。

由于本篇文章较长,大家也可以根据自己的兴趣,点击上面每个问题的直达链接快速查看。

JMWE介绍

在解决上述问题前,我们有必要介绍下jira中一个非常重要的应用。那就是JMWE(Jira Misc Workflow Extensions),官方的介绍如下:

Powerful, all-in-one 
Jira automation app to quickly customize and expand your automated processes.

JMWE是一个功能强大的一体化的Jira自动化应用。其可快速自定义和扩展你的自动化流程。

通过上面的视频我们可以很直观的了解JMWE的功能,下面分别来说下:

提供了预定义好的多种后处理功能,可以支持在卡片拖动状态改变时设置对应的后处理功能,例如清除、修改卡片的某些属性,创建、删除问题,修改角色等,这些可高度定制化的工具可以非常好的帮助我们高度自定义和丰富自己的工作流程。

可通过简化的脚本增强自动化,借助即时 Groovy 语法检查、内联帮助、友好的字段、方法、属性提示和我们的脚本测试器,即使是非编码人员也可以使用 Nunjucks/Jira 表达式轻松扩展工作流程,我们可以构建自己的条件、验证器和发布函数。尤其是脚本测试器,可以直接选择对应的任务进行脚本测试。这个功能对于验证groovy语句写的是否正确来说是非常的好评了,后面会介绍实际例子来说明。

超越工作流程的自动化,可在工作流程和节点转换之外来进行自动化任务的处理。例如,可通过字段/问题更改触发的基于事件的自动化。

基于 JQL 的计划操作:同时对于常规工作流后期功能在过渡上运行。但是,使用计划操作,我们可以计划一个或多个 JMWE 后处理功能来针对 JQL 搜索返回的问题运行,例如:我们可以自动转换任何上报但超过 24 小时仍未解决的问题,这个对于管理测试bug修改时效非常有帮助。

总之:JMWE可以使用后处理函数,条件和验证器,在工作流内部或者外部放大jira的自动化,通过编写简化的脚本,可使自动化功能更强大。同时JMWE拥有大量顶级公司在使用,例如:微软、沃尔玛、P&G、Pfizer等。

解决问题

1.字段必填

问题描述

在使用一段时间后,首先出现的问题就是在创建故事及子任务卡片时,很多重要的字段大家忘记填写了,例如经办人、Sprint名称。这就会导致大家创建好的子任务或者故事在对应的冲刺中看不到,或者筛选自己的任务的时候找不到自己创建的卡片。

但是这两个字段在系统设置中又不能设置成必填,如下:

这两个字段系统默认没有开放设置成必填,那该如何处理呢?

处理思路

既然不能通过系统字段设置直接设置成必填,让其在创建面板字段左侧展示红*,那么可以想办法在点击新建的时候判断如果没有填写Sprint和经办人则不允许其提交,也可以实现相同的功能,这个就需要用到和验证器相关的JMWE了。

解决方法

首先我们需要明确流程,这个是在创建问题的环节我们需要进行做验证,那么就先在工作流节点找到这个转化,选中后点击后处理功能。

点击后处理功能打开工作流转换的编辑页面,我们可以看到左侧该转换对应的验证器,然后添加一个验证器。

在添加验证器到转换页面我们选择Fileds Required Validator(JMWE app)

Fileds Required Validator就是针对字段必填的验证器,可以选择设置任务的所有属性,然后设置是否必填,进入后如下,

我们将字段选择位经办人,当出现错误没有填写时提示:“请填写经办人”。Conditional validation 条件验证我们先不设置,也就是对所有类型的任务,只要在创建这个节点经办人没有填写,这个验证器就会生效,提示用户需填写经办人,并保留在当前页面不允许提交。设置完成后更新,然后在工作流转换的编辑页面进行发布后才能生效。我们看看效果:

当我们点新建时会先校验系统的必填字段,再走验证器验证我们自定义的必填字段条件是否通过,不通过时会在上述位置提示我们设置好的提示语。

同样的对于Sprint字段的必填我们需要约定并不是所有的任务新建都校验,当只有是故事卡片新建时我们才校验Sprint字段是否必填,这里就正好用到了Conditional validation 条件验证,如下:

选择Conditinal validation后会出现条件语句的编写。我们需要判断当前问题的问题类型字段的值为故事条件才能通过,对应的groovy语法如下:

1
issue.get("issuetype")?.name == "故事"

对于不熟悉groovy语法以及jira字段的使用者来说,如何让大家低成本的写出上述的表达式呢?JMWE给出了Help功能,我们可以去查看全局字段、问题的属性、问题的方法、接口等功能,例如这里我们要查找问题属性,则点击issueFields:

首先我们需要选择一个问题的字段,这里在下拉框中我们选择问题类型,然后选择按照字段的id来查找,就会出现下方的方法告诉你怎么写语句找到对应的属性,以及属性的的子字段,同时还会告诉你如何测试找到的属性的值是否是正确的,我们就能够很方便的模仿其给出的示例issue.get("issuetype")?.name == "bug"来改造,把bug类型换成“故事”就OK了,那如何来确保我们修改后的语句是否正确呢,一个是保存后去实际体验下,当然这个对于线上运行的jira服务来说很不友好,很可能会影响到别人的工作,在编写语句的上方我们可以看到JMWE提供了Test Groovy Script功能。我们点击后如下:

让我们选择一个问题来测试,那我们就随便选择一个故事,看看表达式是否能通过,点击Test后如下:

很清晰的告诉我们测试通过,返回的结果类型是boolean类型,返回的值是true。同时如果发现验证结果错误也会有相应提示,我们只需根据错误提示修改上述表达式然后点击Test again就可以继续以当前选中的故事来对新的表达式进行测试了,整体体验还是非常友好的。这样我们验证通过后就可以更新并部署了,效果如下。

2.子任务字段复用

问题描述

在jira字段必填处理好后,大家发现每创建一个子任务的时候都还得再重复填写下修复的版本、模块这两个字段,使得创建一个子任务不是那么方便。

处理思路

既然创建故事的时候已经填写了修复的版本,模块,而且子任务是挂在主任务下的,所以他的修复的版本和模块也一定和主任务的相同,那么我们就可以想办法在创建子任务提交时直接找到其主任务的修复的版本和模块这两个字段,然后把值取出来赋值给子任务就可以了。

解决方法

同样的这里也需要使用到JMWE,在任务创建后执行一个后处理功能,如下:

进入添加后处理功能后选择copyfield value from parent issue(JMWE app),即从父问题拷贝一个字段的值到子问题上。

选择进入后如下:

从上图我们看到这个设置非常方便,我们仅需要选择从父问题拷贝哪个字段,以及把这个字段的值拷贝到当前问题的哪个字段上,然后有一些可选项和条件验证器,这里我们选择仅当子问题没有设置值的时候拷贝,勾选上当出错时给出提示就可以了。就这样点两下就可以完成子任务在创建后自动复用父任务的属性了,而JMWE后台程序则帮我们把里面的实现逻辑都封装好了,其易用性和扩展性还是挺好的。

到这里字段是复用了,但是在创建子任务时界面上还是会出现这两个字段,虽然不用填,这里我们可以通过上一篇文章中介绍的,在界面配置中,只针对我们这个项目的子任务在创建时隐藏这两个字段就好了,这样创建子任务的界面就简洁很多了:

我们填写好问题标题,点下经办人、填写下预估时间就可以提交一个子任务了。虽然只是节省填写了两个字段,但是在项目人数较多,频繁创建任务时还是明显能感觉到好用很多,而且越多的这种小问题被解决,大家就会逐步觉得系统慢慢变好用了,也更愿意去使用并反馈问题从而形成正向循环,并逐渐提升开发效率。

3.快捷筛选项

问题描述

到现在我们创建任务基本上没有太大的问题,但是在一个迭代过程中我们会有多个产品的需求,每个产品希望能够快捷的看到自己提出需求当前的开发进度。同时对于整个版本迭代来说,我们比较关心有哪些还在进行中的需求。就需要我们在冲刺的看版中能够快捷的进行筛选。

处理思路

针对不同产品过滤其负责的需求卡片这个需求,我们可以在冲刺看版中进行JQL筛选,但怎么去筛选对应产品的需求呢,这里我们预先规定所有故事卡片的报告人都指向产品同学,这样我们只需要筛选出报告人是对应产品的故事,且把这些故事下面的子任务都筛选出来就可以了。

针对查看进行中的项目和上面类似,我们需要筛选出故事状态除完成之外的所有故事并筛选出其子任务也就可以实现了。

解决方法

我们进入Sprint的面板配置页面,选择左侧的快速搜索,我们可以在这里新建JQL筛选语句,对于产品卡片的筛选语句如下:

1
issueFunction in subtasksOf("project =DEV AND component =Sp AND reporter = zhangsan")

进行中的筛选语句如下:

1
issueFunction in subtasksOf("project =DEV AND component =Sp AND status in (测试中, 开发中, 开发完成, 待办, 集成中) ")

更多高级筛选的编写可以参考这里,配置好名称后并保存,返回到Spring看版中我们就可以看到刚刚配置的快速筛选项,选中某个产品的需求如下:

筛选当前冲刺进行中所有开发的任务则如下:

可以看到当前Sprint只剩下一个测试中和一个开发完成的需求,同时系统提供了默认的仅我的问题和最新的更新筛选项,到这里我们就拥有了一个比较好用的筛选器。

4.早会看版

问题描述

上述问题解决后我们需要让jira支持好我们每天早上的站立会,那么就需要另外一个看版,以人的维度把大家手上的子任务都清晰的展示出来,同时把大家待解决的问题也都展现出来。

处理思路

针对第一个按照人的维度,这个可以新创建一个看版,看版的展示维度按照经办人来划分就好,第二个就是只展示子任务,那这个就得把故事这种类型给过滤了,同时需要把bug也给大家展示出来,那么就得把bug流程的状态对应到我们现在的开发中的状态。这样就能比较全面的体现出大家开发的进展以及当前所遇到的问题。

解决方法

1.创建看版

看版基于筛选器,卡片的内容是所有研发的内容

1
project = DEV ORDER BY 等级 ASC

配置项目基础泳道基于经办人

2.故事类型过滤

在快速筛选项中配置

1
project = DEV AND component = App AND (issuetype = 子任务 OR issuetype =故障) ORDER BY 等级 ASC

对于App的项目我们可以配置只展示子任务和故障这两种类型,这样就不会有很多故事的卡片多余的展示在基于经办人的看版中。

3.在开发中的任务展示还未解决的bug

虽然上述把bug类型筛选出来了,但是需要把未解决的bug展示在开发中,我们还需要对jira的列进行单独的配置,如下:

我们把bug状态是开放和重新打开的认为是研发同学正在开发中的任务,已经解决的bug放到测试中,这个时候测试需要关注已经关闭的bug,在我们的看版中就不进行关注了。

上述功能配置完成后,可以看下我们最终的站例会看版:

图中可以看出,看板首先是基于人的维度来展示的,所有的子任务标题上都带上了其父任务的标题,没有出现父任务卡片,同时当前正在解决的bug也展示出来了,那么每天开早会的时候就能清楚的知道每个人当前待办的问题,正在开发中的问题以及开发完成的有哪些需求,大家就可以很好的根据这个看板来进行每个人自己工作的汇报。

5.工作日志弹框

问题描述

上面我们已经解决了基本的任务创建、冲刺的快捷查看,每天早上的看板清晰展示,同时大家在创建子任务的时候也都会填写预估的开发时间,但是对于正在开发中的需求,我们想要知道其开发的进展如何,这个就需要用到时间跟踪了。通过让大家自己在子任务卡片下登记工作日志,填写每天在一个问题上消耗的时间,我们就能看到这个任务的进展了,如下:

例如预估2天,第一天工作完成后,点击登记工作日志,录入耗费时间1d,则jira会自动计算剩余1d,当前任务的process是50%。但是一段时间后早会经常发现大家忘记录入工作日志,有时候只有某些同学能够养成这个比较好的习惯,那如何能够确保大家都录入工作日志,让整个项目的进度更清晰呢?

处理思路

这里的想法是,大家都会拖动卡片,当卡片拖动到开发完成或者集成完成时,大家肯定是消耗了时间的,那就可以相办法在大家拖动卡片状态的时候如果能够自动弹出这个工作日志记录弹框就好啦。

解决方法

在解决这个问题的时候最开始一直在尝试使用JMWE官方提供的方法,结果找了一圈没有发现针对节点转换时弹出这样一个弹框的,最后还是在工作流转换中找到了思路:

当我们选中一个转换时可以点击右侧的编辑按钮,在弹框中我们我们发现了一个界面的字段。很容易想象到,这个功能应该是在进行工作流转换时可以配置一个页面,那就好说了,我们可以尝试在上一篇文章中所介绍的页面里自定义一个页面,把工作日志登记这个字段加到页面中,再把这个页面在进入调试和开发完成的转换上绑定不就可以了。

这里很快我们就创建好啦一个工作日志登记页面,然后会到刚刚的工作流编辑页面进行绑定:

绑定完成之后,我们再回到我们的Spring面板中,在任务开发完成时拖动到集成中则会自动弹出工作日志登记页面:

这里需要我们录入耗费时间才可以开始集成,到这里这个问题就很好的解决了,项目中任务的进度也变得更清晰了。

6.故事状态同步

问题描述

前面我们已经解决了工作日志登记,Sprint快速筛选当前未完成的问题,卡片也可以在各个泳道之前进行拖动,但是jira存在的一个问题是子任务大家都记得拖动卡片,但是对于主任务,大家创建的故事,其状态也需要手动的拖动才行,这个总感觉不是很智能,如果主任务能够自动根据其子任务下的卡片的状态变更来综合判断主任务的卡片状态进行自动更改,那我们就可以不用关心主任务卡片的状态了,在任务列表看的也都是实时最新的状态了,那如何实现呢?

处理思路

首先如果对于每一个子任务的状态更新都可能影响到主任务的状态,所以我们可以考虑在子任务状态更新时来判断是否更新主任务,那我们可以先定义好主任务更新的条件:

待办->开发中

故事当前是待办状态,子任务只要有一个从待办状态变为开发中状态的时候我们就认为这个故事是开发中了,那么此时将其状态变为开发中。

开发中->集成中

故事当前是开发中,子任务只要有一个从开发中变为集成中状态,那么我们就认为故事的状态变成了集成中,则自动将故事的状态变成集成中,类似待办->开发中。

集成中->开发完成

故事开发完成的状态,我们的理解是只有所有的开发子任务都调试集成完成,并拖动到开发完成状态了,我们才认为故事的状态变为开发完成,所以应当是最后一个子任务从集成中拖动到开发完成时触发故事的状态变为开发完成。

开发完成->测试中

故事当前状态是开发完成,其下只要有一个子任务的状态从开发完成变成测试中状态时自动将故事的状态变为测试中。

测试中->完成

一般故事的状态变成完成,需要所有子任务的状态都变为完成,主任务的状态才认为是完成状态,所以这个转换发生在最后一个子任务变成完成时,好在jira v8.0之后的版本中自动支持了该功能,在最后一个子卡片拖动到完成时,系统会自动弹框提示是否将主任务的状态变为完成。

通过上面的分析,可以看到,其实所有的状态变更都是从前往后的,这也符合软件开发的流程,所以我们可以一步一步的将故事的状态往后转换。其实总结下来就是两种,一种是只要有一个子任务的状态变为新状态则主任务就变成新的状态,另一种是所有子任务的状态都达到对应的状态时主任务的状态才更新。那么我们就可以在子任务状态发生变更时进行针对性的判断了。

解决方法

首先来说第一种较为简单的,我们这里以故事的状态从待办变为开发中为例,先找到子任务的工作流进入开发进行编辑,然后切换到后处理功能,进行后处理功能添加:

进入后这里直接选择Transition parent issue(JMWE app)

进入到详情页后我们可以看到:

首先我们选择一个对父任务的转换。

进入到转换页面后,先选择我们对应的工作流,然后选择这个工作流下面我们自己命名好的一个流程转换,这里我们选择从 待办->开发中 这个转换对应的就是进入开发,选择后保存,就可以在列表看到了。同时我们需要进行一个条件验证,也就是只有父任务的状态是待办时才进行这个转换,如果父任务已经是开发中了或者是其他的状态也就没必要进行这个转换了,所以在条件验证时我们这样处理:

判断:parentIssue.get("status")?.name == "待办" 也就是父任务的状态是待办,且有一个子任务状态从待办变为开发中时才会触发父任务进行上述配置的转换,主任务状态随之转换为开发中。

第二种情况同样也是针对父任务的状态转换,但是需要判断的条件稍微多一点,这里我们以集成中到开发完成先来分析下:

1.因为每个故事测试同学会创建测试的子任务卡片,但是开发完成状态其实跟测试有没有开始介入没有什么关系,这样在所有的子任务中,我们首先需要排除测试同学创建的卡片。

2.除了测试同学创建的卡片外其他都是开发创建的子任务,这些子任务除了当前拖动的这个子任务外,其他子任务都应该处于开发完成及以后的状态,这时拖动当前子任务到开发完成才会执行主任务的状态转换。

3.拖动当前子任务时,父任务的状态应该正好处于集成中,才执行将其状态变更为开发完成。

有了上面的分析下面我们来进行配置,首先还是进行父任务状态转换的配置:

这里设置转换为完成集成,对应的就是集成中->开发完成,然后我们再看下条件校验:

首先我们找到父任务下的子任务数量,进行逐个遍历,判断子任务的经办人在项目中的角色不是测试(这里经办人在项目中的角色参考上一篇文章中介绍的对于项目角色的配置,我们可以把测试同学都绑定测试这个项目级别的角色)同时遍历到的问题不是当前问题,然后判断其状态,如果有集成中,待办或者开发中这几个状态的则认为还有至少一个任务不是开发完成的,这个时候直接返回false不进行父问题的转换,如果所有子任务判断都通过后,再判断当前父任务的状态是集成中,则返回true,执行转换。

Debug:在编写脚本的时候因为有些逻辑可能会比较长,我们可以简单的看下groovy语法去编写正确的脚本,同时对于关键的判断或者对于某些表达式我们需要测试下其属性的值和结果是否是我们的预期,我们就需要有debug功能了,但是不巧的是jmwe暂时没有提供断点debug或者是println("") 日志输出,这里给大家介绍下我的处理方式:

我们可以在想要看debug的地方将代码写好,直接进行return返回。然后点击下上方的Test again,则在下面的输出中就会显示我们表达式的结果,这个方式还是非常有用的,同时也希望JMWE能够支持日志打印输出的功能。

好了,上面的代码配置好后,我们看下效果:

这是在转换前,有两个测试的任务,还有两个开发的任务,其中一个开发完成,一个是集成中状态,所以父任务当前也是集成中状态,当我们把集成中状态的这个任务拖动到开发完成时:

可以看到故事DEV-2306的状态就变成开发完成了,同时没有受到连个测试任务的干扰,到这里故事的状态就可以实时的根据大家对子任务状态的更改进行同步了。我们也就只需要在创建故事的时候关注下故事的内容,在后面的开发中只需要关注我们自己的子任务就ok了。这样故事的状态是对的,快捷筛选不管什么时候就都能正常使用了。

总结

经过一段时间的使用以及不断的收集大家在使用中的反馈,我们解决了多个类似上面的问题,逐步的优化了jira的使用体验。可以看到这个过程中JMWE给了我们很大的支持,其内置的多个场景下的转换工具可以帮助我们快速的进行jira流程的自定义配置。当后面还有更多有意思有价值的的优化时还会继续给大家分享。

JMWE在jira中如此好用及强大,正如JMWE介绍视频中说的那样:

If you’re not using JMWE, you’re doing it wrong.

在jira使用的便捷性问题解决后,后面我们就要思考的是jira如何帮助我们进行工程效率的提升,尽请期待下一篇文章。