公司通过gitlab托管代码,采用jira作为敏捷实践的管理工具,每次发布的时候拉出当前迭代的所有故事做发布计划.
然而实际上因为某些原因,基本上无法实现每次迭代的所有故事都能发布.只有在分支上测试完成合并到 master上的故事才会被发布.
那么就想着能不能在分支合并到master的时候在jira上打个标签,这样在jira上一筛选就知道哪些故事是可以发布的了
好在gitlab有webhook功能,能够在触发某些操作的时候调用自定义的接口传输相关操作的信息,而jira也提供了相应的api来方便读写,那么只需要发布一个服务提供接口给webhook调用,解析传过来的参数,符合条件的情况下去调用jira的api修改标签,这个方案也就实现了.
本文相关版本信息
GitLab Community Edition 11.1.4
JIRA v7.13.5
python 3.5.4
Flask 1.1.2
requests 2.24.0
提前约定
在git创建分支时分支名称需要包含jiraId
我们项目组是直接以jiraId+故事标题命名分支
编写程序
图快速方便所以用python写的,结果后面部署费了不少事
webhook调用接口传递参数解析
文档: https://docs.gitlab.com/ee/user/project/integrations/webhooks.html
参数是json形式的
主要取出其中3个参数
-
object_attributes.state
gitlab设置的trigger是合并事件,实际上会在申请(opened),关闭(closed)和完成合并(merged)3个情况触发,所以要判断是否是完成合并的调用
-
object_attributes.target_branch
target_branch 是为了确认是合并到master的请求,合并到其他分支的请求不处理
-
object_attributes. source_branch
source_branch 是为了取出jiraId以进行后续操作
jira接口调用
文档: https://developer.atlassian.com/server/jira/platform/jira-rest-api-examples/#editing-an-issue-examples
从source_branch利用正则截取出jiraId,拼装并调用接口地址
附三个修改标签的传参,第一个是追加,后两种是覆盖设置
#增加
{
"update" : {
"labels" : [{"add" : "标签内容"}]
}
}
#设置
{
"fields" : {
"labels": ["标签内容"]
}
}
{
"update" : {
"labels" : [{"set" : ["标签内容"]}]
}
}
PS:
建议先用postman之类的工具先调试一下jira的接口,如果报错
Field 'labels' cannot be set. It is not on the appropriate screen, or unknown.
那就需要联系jira管理员,在项目的screens(项目管理->界面)中开启相关字段的api读写权限
完整源码如下:
# -*- coding: utf-8 -*-
from flask import Flask,request
import requests
import re
baseUrl = 'http://jira.sunjianbo.com:8080/rest/api/2/issue/'
app = Flask(__name__)
@app.route("/", methods=["GET", "POST"])
def test():
# addTag2Jira("DB19236-2398 324扥矿赛肯")
return "hello world"
@app.route("/merged", methods=["GET", "POST"])
def merged():
# print(request.headers)
# print(request.json)
# print('---')
body = request.json
object_attributes = body['object_attributes']
state = object_attributes['state'] # opened,closed,merged
source_branch = object_attributes['source_branch']
target_branch = object_attributes['target_branch']
if state == 'merged' and target_branch == 'master':
# 已合并到master
print('是已合并到master的请求,开始修改jira标签')
addTag2Jira(source_branch)
else:
print('不是合并到master的成功请求,而是合并到['+target_branch+']的['+state+"]请求")
return ""
def addTag2Jira(source_branch):
# 取得分支jira id
matchObj = re.search(r"DB\d+-\d+", source_branch)
if matchObj:
print("匹配出的jiraId: ", matchObj.group())
jiraId = matchObj.group()
# 去相应jira故事中打一个uat标签
url = baseUrl + jiraId
messagebody = '''
{
"update" : {
"labels" : [{"add" : "UAT"}]
}
}
'''
result = fun_put(url, messagebody)
print(result)
if result.status_code == 204:
print('修改成功: ' + url)
else:
print('修改失败: ' + source_branch)
else:
print("分支名称上找不到jiraId: " + source_branch)
def fun_put(url, messagebody):
headers = {'content-type': 'application/json', 'Accept-Charset': 'UTF-8'}
r = requests.put(url, data=messagebody, headers=headers, auth=('username', 'passwd'))
print(r.status_code)
return r
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080)
部署
部署这里有个插曲
公司服务器是离线的,所以我先离线安装了python3,然后打算安装virtualenv时报了一个ssl的错误,明明是离线安装,为毛会涉及到ssl,咱也不知道,咱也不敢问,推测是python3安装的有点问题,依赖的openssl之类的在测试机上不太全吧
折腾了半天没搞定,考虑到是测试服务器我就瞎搞了一把
用了
pip3 install -r requirements.txt --proxy=代理服务器IP:端口号
代理走了我本地电脑在线安装了Flask和 requests,瞬间就解决了(给机智的我点个赞(◔◡◔))
设置gitlab上的webhook
settings->integrations->填写url->Trigger勾选Merge request events
->嫌麻烦我禁用了ssl,没有实际测试一下行不行->保存
)