相关代码提交至 GitHub -> github.com/wangyuheng/… 欢迎提交 issue
What
监听Gitlab Hook事件, 紧急消息通过钉钉机器人发送至钉钉群组, 并@(提醒)相关方. 同时自动流转issue的pipeline.
效果
新建紧要issue会在钉钉群内收到下列消息
xxx 创建了一个 [P0 issue] 给你,请尽快确认并处理
Link -> https://gitlab.com/wangyuheng77/integration/issues/1
title -> 提供issue变更钉钉消息通知
@wangyuheng
已发布的issue会
- issue 自动从
Doing变更为Verify - issue assignee 从开发者变更为author
- 钉钉群收到消息提醒 @author 进行验收工作
Why
- 紧急事项实时提醒到人
- 定制pipeline & 自动流转
为什么不通过钉钉自带的gitlab机器人 或者 gitlab notify email?
- 发送的消息过多, 会忽略有意义的信息
- 不能 @ 到相关的人, 达不到提醒的作用
How
gitlab -> keeper: listen event
keeper -> keeper: resolve event msg
alt isEmergency
keeper -> Dingding: send msg to group by robot
keeper -> gitlab: put next pipeline
note left of keeper: change assignee | close issue
end
gitlab hook
在gitlab项目中配置hook地址并保存
pipeline
根据团队状况制定pipeline, 基于事件自动流转. 比如:
- 新建
:WIP MR时流转至doing - CICD流转至deploy
- 发布成功后流转至verify并修改assignee为author
backlog -> todo
todo -> doing
doing -> deploy
deploy x--> doing
deploy -> verify
verify x--> doing
verify -> close
Emergency issue
通过label判断是否为紧要消息, 比如 Bug、P0.
start
:receive hook;
if (closed?) then (yes)
if (changedAssignee?) then (yes)
if (isEmergency?) then (yes)
:send emergency message;
endif
else (changedToVerify)
:send verify message;
endif
endif
end
core code
private fun handlerIssue(body: JSONObject) {
if (GitlabHookBodyHelper.isClose(body)) {
//已关闭的issue不做处理
return
}
val changedAssignee: GitlabHookBodyHelper.Assignee? = getChangedAssignee(body)
log.info("handler issue changedAssignee: $changedAssignee")
val labelTitles: MutableSet<String> = GitlabHookBodyHelper.listLabelTitle(body)
log.info("handler issue labels: $labelTitles")
// 是否变更assignee
if (changedAssignee != null) {
val developer = developerRepository.findByUsername(changedAssignee.username!!)
// 为开发人员 && label为todo且不在进行中
if (developer != null && labelTitles.isTodo() && !labelTitles.isProcessing()) {
when {
labelTitles.isBug() -> sendBugMsg(body, developer.mobile)
labelTitles.isP0() -> sendEmergencyMsg(body, developer.mobile)
else -> log.info("ignore issue change! labelTitles -> $labelTitles")
}
}
} else {
if (GitlabHookBodyHelper.isFirstChangeToVerifyLabel(body)) {
val author = getAuthor(body)
val assigneeUsername = editAssignee(body, author)
val mobile = developerRepository.findByUsername(assigneeUsername)?.mobile
if (null != mobile) {
sendVerifyMsg(body, author, mobile)
}
}
}
}
小技巧
非内网部署gitlab如何开发调试
ngrok 实现内网穿透
brew cask install ngrok
验证阶段的issue关闭不及时
先自动closeissue, 并dingding提醒. 如果有问题可以reopen并自动流转至Doing.