基于Gitlab进行开发团队管理的尝试——01.周报

周报的目的在于团队间的沟通交流,总结每周的得失经验。不要流于形式,成为流水账。

What

通过Gitlab issue管理周报,每周定时自动排版并发送周报邮件

Why

痛点

  1. 排版格式繁琐,outlook对程序员不算友好
  2. 不利于归档管理
  3. 督促团队写周报 -> 当然这个主要原因在于leader。如果你写的周报没人关心,没人过问,那么为什么还要写?

优势

  1. markdown语法 + 统一管理主题、收件人等繁琐信息,让编写者专注于周报内容本事
  2. issue模板统一风格,提升周报质量&价值
  3. 归档管理周报信息,通过issue本身的功能,可以进行人员索引、labels管理等
  4. 每周定时扫描并发送邮件。如果扫描时没有发现对应developer的周报issue,那么就广播一封remind邮件。

三体中逻辑通过摇篮系统,成为了执剑人(Damocleser),建立黑暗森林威慑。

整体流程如下:

How

对周报编写方来说,只需要在issue中选择周报模板并添加对应label即可。

Gitlab 设置

  1. 添加label,命名为周报
  2. 在项目 .gitlab/issue_templates 目录下新建周报.md作为模板,可以在新建issue时被选择。
1
2
3
4
5
6
7
8
9
10
11
## 上周最重要的“3”件事

1.

## 本周最重要的“3”个目标

1.

## 遇到的问题和感受

1.

扫描job

基于kotlin实现一版定时任务

dependents:

  1. h2 -> 内存数据库,用于存储developer信息
  2. commonmark -> 用于markdown转换为html格式
  3. okhttp & fastjson -> gitlab api调用及解析

核心代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
@Scheduled(cron = "\${weekly.cron}")
fun checkWeeklyIssue() {
log.info("start weekly job ! weeklyProjectList:{}", weeklyProjectList)
val nameMapWeeklyIssue = weeklyProjectList.flatMap {
gitlabClient.listOpenProjectIssue(it)
}.filter { issue ->
issue.getJSONArray("labels").contains(WEEKLY_LABEL)
}.filter { issue ->
!issue.getJSONArray("labels").contains(WEEKLY_ARCHIVE_LABEL)
}.map { issue ->
val name = issue.getJSONObject("author").getString("name")
name to WeeklyIssue(issue.getIntValue("project_id"), issue.getIntValue("iid"), name, issue.getString("description"))
}.toMap()
log.info("map gitlab issue data! nameMapWeeklyIssue:{}", nameMapWeeklyIssue)
// 如果一个记录也没有,可能是节假日导致。此时不发生提醒
if (nameMapWeeklyIssue.isNotEmpty()) {
developerRepository.findAll().forEach {
val weeklyIssue = nameMapWeeklyIssue[it.name]
this.sendEmail(weeklyIssue, it)
}
}
}

private fun sendEmail(weeklyIssue: WeeklyIssue?, developer: Developer) {
if (weeklyIssue == null) {
log.info("send a remind email! name:{}", developer.name)
emailClient.send(fillSubject(developer.name), "I am ${developer.name}. I do not write a weekly! Please remind me when you see me!", developer.receivers)
} else {
log.info("send a weekly email! name:{}", developer.name)
val content = renderer.render(parser.parse(weeklyIssue.description))
emailClient.send(fillSubject(developer.name), content, developer.receivers)
gitlabClient.editIssueLabels(weeklyIssue.projectId, weeklyIssue.issueId, WEEKLY_ARCHIVE_LABEL, true)
}
}

private fun fillSubject(name: String): String {
val lastWeek = LocalDate.now().minusWeeks(1)
return "[周报][XX工程][$name][${lastWeek.with(DayOfWeek.MONDAY)}~${lastWeek.with(DayOfWeek.SUNDAY)}]"
}

问题

  1. 节假日如何处理? 如果一包含周报label的issue都没有,认为是节假日,跳过后续处理。非周一发送,由Leader手动触发
  2. SLA?不保障,手动触发即可