曹逸君 Blog

11月 11, 2013

git hooks 发送邮件

前面用git得post-receive钩子实现了自动部署,很是舒畅,然后想着自动群发个邮件,项目组得人都能及时得知仓库更新、项目进度岂不是很好。 我搜到得实现方式有用sendmail得,有用smtp的。但因为我很懒。已经用过web.py得sendmail.简洁到根本不想去搞其他配置。像这样:(其实用python得标准库也很简单。)

import web
web.config.smtp_server = 'smtp.gmail.com'
web.config.smtp_port = 587
web.config.smtp_username = 'qunfazhuanyong@gmail.com'
web.config.smtp_password = 'mima'
web.config.smtp_starttls = True

发送邮件就是web.sendmail('qunfazhuanyong@gmail.com', receiver, title, msg)

非常赏心悦目,然后我十分作死得选择继续用bash写post-receive钩子。

bash简直大坑,各种奇怪的惯例,扭曲得语法,和系统工具的紧密利用。不仔细看遍bash手册会写得非常痛苦。各种搜索。最终写出得post-receive:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#!/bin/sh
#auto deploy and sendmail

echo 'auto deploy'
RET=`git --git-dir=/home/git/app.git/ --work-tree=/webroot/app reset --hard`
STAT=$?
if [ $STAT -eq 0 ]; then
    git show |echo $'new chc deployed\n'"$(cat)"|./hooks/sendmail.py
    echo 'deployed!'
else
    echo $'deploy error\n'"$RET"|./hooks/sendmail.py
    echo "=口= something went wrong. $STAT"
fi

坑点如下:

\n转义?单引号加$,echo -e也可以

$'deploy error\n'

字符串链接?放在一起就是

$'deploy error\n'"$RET"

还有系统方面得一个概念。参数和标准输入是不一样得。

./sendmail.py 嘿是我 其实没什么事 sys.argv == ['sendmail.py','嘿是我','其实没什么事']

./test.sh 卧槽你想干嘛

$0==./test.sh $1==卧槽你想干嘛

以上是参数。以下分别为python和bash里获取标准输入

sys.stdin.read() 当然还有readline readlines。我觉得这里直接read()最省事。

"$(cat)" 巨坑bash来了,cat不加参数得时候就是cat /dev/stdin,从标准输入输出到标准输出。然后用$(命令)取值。用双引号变量才会取值,换行符才会保留

深感bash真不友好。python我只要随便搜搜,大概知道要用sys.stdin得库。help看下帮助马上就知道要用read还是readline还是readlines。bash只能不停搜索搜索。看手册都不知道要看哪儿。一开是我还以为是echo把换行给去掉了。=。=

然后便是最强大得管道了。也就是:|

关于管道

完整的sendmail.py代码如下:

 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
#! /usr/bin/env python
# coding=utf-8
#    sendmail
#    C19<classone2010@gmail.com>

import web
import sys
web.config.smtp_server = 'smtp.gmail.com'
web.config.smtp_port = 587
web.config.smtp_username = 'qunfazhuanyong@gmail.com'
web.config.smtp_password = 'mima'
web.config.smtp_starttls = True

#receiver list
receiver = ['dev1@gmail.com','dev2@gmail.com','dev3@gmail.com','dev4@gmail.com']
def sendmail(title,msg):
    print("sending mail {0}".format(title))
    web.sendmail('qunfazhuanyong@gmail.com', receiver, title, msg)

if __name__ == '__main__':
    if len(sys.argv) > 2:
        sendmail(sys.argv[1],sys.argv[2])
    else:
        stdin = sys.stdin.read()
        stdin = stdin.split('\n',1)
        sendmail(stdin[0],stdin[1])

其实,如果全部用python实现要舒服得多。。=。=

好吧。真就有纯Python的实现。只需配置即可。 https://github.com/mhagger/git-multimail