当一个团队使用git进行开发时,一旦代码更新就需要通知团队成员。现在利用git的钩子文件以及python写的脚本自动去帮我们做成这件事。
git的钩子文件分为服务器(远端仓库)钩子文件和客户端(本地)钩子文件,进行脚本编写时要区分好不同端所用的钩子文件。编写错误会导致邮件无法发送,
一般来讲,只编写服务端的钩子文件,服务端钩子文件主要有三种:
pre-receiver: 处理来自客户端的推送操作时,首先执行的钩子文件
update: 与pre-receive类似,会为每一个被推送的分支各运行一次
post-receive:整个过程完结以后运行,可以用来更新其他系统服务或者通知用户
服务端代码更新完后,最后启动的是post-receiver,因此我们来编写它的脚本文件:
1.进入git仓库下的hooks里面,新建名为post-receiver的shell脚本文件,向其中写入:
#!/bin/sh
#一定要编写这句话,清除GIT自己设置的根目录,否则无法正常执行下一句
unset GIT_DIR
#用python2执行py文件,就是cmd命令,需要指定py文件的绝对路径
python D:/testemail/hooks/send.py
2.send.py文件中的代码:
邮箱服务器一般支持POP3 SMTP IMAP,另外还有Exchange。前三种需要进入邮箱查找服务器名称以及设置授权码。下方代码是选取了SMTP服务器发送邮件。
# coding:utf-8
import smtplib as sm
from email.mime.text import MIMEText
from subprocess import check_output
#发送邮箱的smtp服务器
mail_host = 'smtp.163.com'
#发送邮箱
sender = 'xxxxxx@163.com'
#发送邮箱的smtp的授权码(非邮箱的登陆密码)
password = 'xxxxxxxx'
#接收者邮箱
receiver = 'xxxxx1,xxxxxx2'
#邮箱主题
subject = 'Code Update Notification'
def Info():
'''
该函数主要用来获取最近一次更新记录,并提取主要信息:
author
date
comment
'''
#使用subprocess的check_output函数来捕获git命令后的
#标准输出,以获取最近一次更新记录,该记录是一个字符串
log = check_output(['git','log','-l','-p'])
#对字符串进行分割,以获取相关信息author date comment
detail = log.split('\n\n')
#更新者
updater = detail[0].split('\n')[1].replace('Author','Updater')
#更新时间,去掉最后的更新次数信息
update_time = detail[0].split('\n')[-1].replace('Date','Update time')[0:-6]
#注释,并去掉左右两边空格
try:
comment = 'Comment:'+detail[1].strip()
except:
comment ='Comment: '+"Sorry,the updater didn't comment."
return (updater,update_time,comment)
def Format(updater,update_time,comment):
'''
排版信息
'''
msg = """
<h6 style='color:red'>Hi,buddy!</h6>
<h6 style='color:red;text-indent:2em'>
The code has been updated,the following is details:
</h6>
<h6 style='color:red;text-indent:4em'>{0}</h6>
<h6 style='color:red;text-indent:4em'>{1}</h6>
<h6 style='color:red;text-indent:4em'>{2}</h6>
<h6 style='color:red;text-indent:2em'>If any question,please contact the updater</h6>
""".format(updater,update_time,comment)
msg = MIMEText(msg,'html','utf-8')
return msg
def send_email(msg):
'''
发送邮件
'''
msg['From'] = sender
msg['To'] = receiver
msg['Subject'] = subject
smtpObj = sm.SMTP(mail_host)
smtpObj.login(sender,password)
smtpObj.sendmail(sender,receiver.split(','),msg.as_string())
smtpObj.quit()
if __name__ =='__main__':
updater,update_time,comment = Info()
msg = Format(updater,update_time,comment)
send_email(msg)
Exchange协议发送邮件send.py:
#coding:utf-8
from exchangelib import DELEGATE,Account,Credentials,Configuration,NTLM,Message
from exchangelib import Mailbox,HTMLBody
from exchangelib.protocol import BaseProtocol,NoVerifyHTTPAdapter
from subprocess import check_output
import re
try:
import sys
#将默认编码ASCII修改成UTF-8,改善对中文的处理
reload(sys)
sys.setdefaultencoding('utf-8')
except:
pass
def Info():
'''
该函数主要用来获取最近一次更新记录,并提取主要信息:
author
date
comment
'''
#使用subprocess的check_output函数来捕获git命令后的
#标准输出,以获取最近一次更新记录,该记录是一个字符串
log = check_output(['git','log','-1','-p']).decode()
#更新者
updater = re.search(r'(Author: [\s\S]*?) <',log).group(1)
updater = updater.replace('Author','Updater')
#更新时间,去掉最后的更新次数信息
update_time = 'Date: '+re.search(r'Date: ([\S\s]*?)\n\n',log).group(1)[:-6]
#注释,并去掉左右两边空格
try:
comment = 'Comment: '+ re.search(r'Date: [\S\s]*?\n\n([\S\s]*?)\n',log).group(1).strip()
except:
comment ='Comment: '+"Sorry,the updater didn't comment."
return (updater,update_time,comment)
def Format(updater,update_time,comment):
'''
排版信息
'''
msg = """
<p style='font-family:"黑体"'>Hi,buddy!</p>
<p style='font-family:"黑体";text-indent:2em'>
The code of server has been updated,the following is details:
</p>
<p style='text-indent:4em'>{0}</p>
<p style='text-indent:4em'>{1}</p>
<p style='text-indent:4em'>{2}</p>
<p style='font-family:"黑体";text-indent:2em'> The email was automatically sent by GIT server.If any question,please contact the updater</p>
""".format(updater,update_time,comment)
return msg
def send_email(msg):
'''
发送邮件
'''
#用来消除SSL证书错误
BaseProtocol.http_ADAPTER_CLS = NoVerifyHTTPAdapter
credential = Credentials(username,password)
act = Account(primary_smtp_address=account,credentials=credential,autodiscover=True,access_type=DELEGATE)
mail = Message(
account = act,
subject = subject,
body = HTMLBody(msg),
to_recipients = [Mailbox(email_address=i) for i in reciever]
)
mail.send_and_save()
if __name__=='__main__':
#邮箱
account = 'xxxxxx'
#接收者列表
reciever = ['xxxxx@163.com',
'xxxxx@126.com',
'xxxxx@qq.com',
'xxxxx@qq.com']
#域账号:域名\用户名
username = r'xxxx\xxx'
#密码
password = 'xxxxx'
#解析git最新历史记录
updater,update_time,comment = Info()
#用HTML排版解析信息
msg = Format(updater,update_time,comment)
#邮箱主题
subject = 'Code updated notification – {}'.format(updater.replace(':',''))
#发送邮件
send_email(msg)
邮件脚本的编写其实还是有些不足的,比如收件者多的时候,代码提交速度会很慢,这时候我们可以采用python的多线程或者多进程去发送邮件,又比如,代码提交者也会收到代码更新的邮件,这时候我们可以自己写一个基于git configure信息编写过滤函数。