公司一直倡导测试要对开发改动的代码进行 codereview。
小的需求一般在一个项目里面几个 commit 的情况下,的确所花的 review 成本也不高。
但是一旦项目比较大型,涉及的代码仓库比较多,且前期开发提交频繁的情况下,一旦等到提测才进行 codereview,这个堆积的工作量就太大了,看着就有一种不想 review 的感觉呢。
而且这么多的 commit 的情况下,一次性光看 commit message 都觉得负担很重,谈何 review?
既然一次过 review 的量太大,我们为何不尝试每天抽时间完成当天提交的 review 呢?
在提测之前提前介入 review,还能及时发现问题,把 bug 扼杀在开发阶段~
于是我们基于 jenkins 和钉钉机器人做了一个每日 git commit 汇总钉钉通知小工具。
以下代码 python 版本为 2.7.10。
def getCommitMessages( repos,day_count ):
repos_list = repos.split(";")
summary=[]
# 遍历列表中所有仓库
for repo_str in repos_list:
# 执行前清空临时文件夹
deleteDir(tmp_path)
repo = json.loads(repo_str)
project_name = repo['url'].split('/')[-1]
project_title = project_name+'-'+repo['branch']
repo['title'] = project_title
work_dir = os.path.join(tmp_path,project_title)
if 'http' not in repo['url']:
repo['error']='仓库链接仅支持http/https的格式,请修改仓库链接。当前的仓库链接为:{}'.format(repo['url'])
summary.append(repo)
continue
try:
# 克隆到本地
git.Repo.clone_from(repo['url'], work_dir, branch=repo['branch'], progress=None)
repository = git.Repo(work_dir)
results=[]
# 获取每一个n天以内的commit并打印出时间和拼接详情链接
today = datetime.now()
last_commit_date = time.mktime((today - timedelta(days=day_count)).timetuple())
commits=repository.iter_commits(rev=None,paths='', max_age=last_commit_date)
for commit in commits:
result={}
commit_date = datetime.fromtimestamp(commit.committed_date)
result['date'] = str(commit_date)
result['committer'] = commit.author.name.encode('utf-8')
# 需要对markdown的标签进行转义
result['message']= commit.message.replace('# ','\# ') \
.replace('* ',"\* ") \
.replace('\r\n\r\n',' >>> ') \
.replace('\n',' ') \
.replace('\r',' ') \
.split('Conflicts:')[0] \
.encode('utf-8')
result['url']= '{}/commit/{}'.format(repo['url'], str(commit))
results.append(result)
repo['commits']=results
if results == []:
repo['error'] = '暂无更新'
except Exception as e:
repo['error']='仓库克隆失败,请检查是否仓库地址有误或是否有权限问题。仓库地址:{}'.format(repo['url'])
print (str(e))
summary.append(repo)
return summary
# 生成对应格式的的message
def summaryToMarkdown( summary ):
message=''
for repo in summary:
message += '#### {}: \n'.format(repo['title'])
message += '> \n'
if repo.has_key('error') :
message += repo['error']+"\n\n"
continue
for commit in repo['commits']:
message += '* 【{} **{}**】[{}]({}) \n'.format(commit['date'], commit['committer'], commit['message'], commit['url'])
message += '\n\n'
return message
# 发送钉钉消息
def sent_dingding_message(token,content,
template="""## 最近24小时内git commit汇总情况如下: \n {}"""):
headers = {'content-type': 'application/json'}
payload = {
"msgtype": "markdown",
"markdown": {
"title": "每日git commit汇总",
"text": template.format(content)
}
}
s = requests.session()
resp = s.post('https://oapi.dingtalk.com/robot/send?access_token={}'.format(token),
headers=headers,
data=json.dumps(payload))
if resp.status_code != 200:
resp.encoding="utf-8"
print(resp.text)
raise Exception("消息发送失败")
pip install gitpython
shell
# 这里修改钉钉机器人token
export token=token1,token2
# 按照如下格式配置需要汇总的仓库和分支,通过英文分号;隔开,同一个仓库的多个分支需要分开两条写
export repos='{"url":"http://github.com/xx/xx","branch":"develop"};{"url":"http://github.com/xx/xx","branch":"master"}'
python gitCommitNotice.py