简述

此脚本为 git 日报通知脚本,将 gitlab 中对应项目组中的所有项目 git commit 信息 html表格 形式发送给需要通知的人,可用与项目 敏捷开发 时进行使用。

环境说明

依赖工具

  • git 2.9.3
  • sendemail
  • jq

操作环境说明

  • Centos7 7.9.2009
  • Gitlab : 13.10.2

依赖准备

编译安装 git

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
yum remove git  # 卸载系统当前 低版本 git

wget https://github.com/git/git/archive/refs/tags/v2.9.3.zip # 下载源码

unzip v2.9.3.zip 

cd git-2.9.3/

make configure  

./configure prefix=/usr/local/git/  # 配置 git 安装目录

make -j8 && make install  # 编译并且安装

ls /usr/local/git/
bin  lib64  libexec  share

vim /etc/profile # 添加至 path 变量中
export PATH=/usr/local/git/bin

source /etc/profile # 使 path 变量生效

git version
	git version 2.9.3

使用 yum 安装 其他依赖工具

1
yum install sendemail jq -y

脚本初始化

获取 gitlab 中的 api token

image-20210413141815261

image-20210413141922548

点击创建,复制生成的 key

image-20210413142042056

新建组并获取组 id

image-20210413142645928

image-20210413142715324

image-20210413142728912

获取到当前项目的 组id 3

新建测试仓库

在刚才新建的项目组中,新建几个参考,并在这几个仓库中添加几条 commit message。

image-20210413143108201

添加 commit message 数据

image-20210413143334606

image-20210413143320161

测试执行脚本

最终脚本如下所述,相关变量参数,根据实际情况更改即可

  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
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#!/bin/bash
source /etc/profile
GITLAB_TOKEN='xxx' # gitlab api token
GROUP_ID=3 # 组 id
GROUP_NAME='git-log'  # 对应的 gitlab 组
GITLAB_WEB_URL='http://gitlab.treesir.pub' # gitlab 地址
GITLAB_URL='http://root:xxx@gitlab.treesir.pub'  # 拥有当前项目 git clone 权限的账号密码

DATE=`date +%Y-%m-%d`
HTML_NAME="$DATE-$GROUP_NAME".html
DATA_DIR=/data/scripts/gitdata/"$GROUP_NAME"
GITWORK=/data/scripts/gitwork/"$GROUP_NAME"
#EMAIL_LIST=("user1@gmail.com" "user2@qq.com")  # 定义需要通知的人员,邮箱地址
EMAIL_LIST=("xxx@dingtalk.com")
DATA_SAVE_TIME=180 # 生成的 htlm 保存时长
HTML_PATH_NAME="$DATA_DIR"/"$HTML_NAME"
IFS=$'\n'
RETRY=0
SMTP_EMAIL='xxx@163.com'
SMTP_SERVER='smtp.163.com'
SMTP_AUTH='xxx'

mkdir -p "$GITWORK" && mkdir -p "$DATA_DIR"
GIT_DATE="`date -d '1 days ago' +%Y-%m-%d` 18:50:00" # 从上一天的 下午 6:50 开始计算 commit

# 如果文件存在就删除
if [ -f "$HTML_PATH_NAME" ]
then
        rm -rf "$HTML_PATH_NAME"
fi

# 获取项目中 仓库的名称
GITLAB_JSON=`curl --header "Authorization: Bearer $GITLAB_TOKEN" "$GITLAB_URL/api/v4/groups/${GROUP_ID}" 2>/dev/null`


# 生成 html 文件上半部分
echo """<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
table{
width: 800px;
height: auto;
border: 1px solid #999;
color: #000;
margin: 100px auto;
text-align: left;
}
table  caption{
font-size: 20px;
font-weight:bold;
padding-bottom: 10px;
}
.title{
border: none;

}
table th{
background-color: #999;  
opacity: 0.8;
height: 35px;
}
table td{
height: 20px;
background-color: #333;
color: seashell;
font-size: 14px;
}
</style>
</head>
<body>
""" >> "$HTML_PATH_NAME"

for REMONAME in `echo "$GITLAB_JSON"|jq .projects[].name|awk -F '"' '{print \$2}'`
do
        # 下载镜像代码
        if [ ! -d "$GITWORK/$REMONAME" ]
        then
                cd "$GITWORK"
                git clone "$GITLAB_URL/$GROUP_NAME/$REMONAME".git
        else 
                cd "$GITWORK/$REMONAME"
                git pull
        fi

        for GIT_BRANCH in `git -C "$GITWORK/$REMONAME" branch -a|grep origin|grep -v 'HEAD'|awk -F 'remotes/origin/' '{print $2}'`
        do
                cd "$GITWORK/$REMONAME"
                git checkout "$GIT_BRANCH"
                git pull
                if [ `git log --date=format:'%Y-%m-%d %H:%M:%S' --pretty=format:"%ad,%an,%s,%h" --since="$GIT_DATE"|grep "-" |wc -l` -ge 1 ]
                then
                        echo """
<table>
<caption>项目和分支名称: $REMONAME $GIT_BRANCH</caption>
<tr class="title">
<th>提交时间</th>
<th>提交人</th>
<th>提交内容</th>
<th>提交ID</th>
</tr>
                        """ >> "$HTML_PATH_NAME"
                        for COMMINT in `git log --date=format:'%Y-%m-%d-%H:%M:%S' --pretty=format:"%ad|%an|%s|%h|%H" --since="$GIT_DATE"`
                        do 
                                if [ `echo $COMMINT|grep 'Merge'|wc -l` -eq 1 ]
                                then
                                        continue
                                else
                                        submit_time=`echo $COMMINT|awk -F '|' '{print $1}'`
                                        submit_one=`echo $COMMINT|awk -F '|' '{print $2}'`
                                        submit_message=`echo $COMMINT|awk -F '|' '{print $3}'`
                                        submit_id=`echo $COMMINT|awk -F '|' '{print $4}'`
                                        submit_long_id=`echo $COMMINT|awk -F '|' '{print $5}'`
                                        echo """
<tr class="title">
<td>"$submit_time"</td>
<td>"$submit_one"</td>
<td>"$submit_message"</td>
<td><a href="$GITLAB_WEB_URL/$GROUP_NAME/$REMONAME/-/commit/$submit_long_id">"$submit_id"</a></td>
</tr>
                                        """ >> "$HTML_PATH_NAME"
                                fi
                        done
                        echo "</table>" >> "$HTML_PATH_NAME"
                fi
        done
done

echo """
</body>
</html>
""" >> "$HTML_PATH_NAME"

if [ `cat "$HTML_PATH_NAME" |grep tr|wc -l` -gt 0 ]
then
        for EMAIL in ${EMAIL_LIST[@]}
        do
                /usr/bin/sendemail -f "${SMTP_EMAIL}" -u "$DATE ${GROUP_NAME}项目 日报请查收~" -s "${SMTP_SERVER}" -o tls=no -o message-content-type=html -o message-charset=utf8 -xu "${SMTP_EMAIL}" -t "$EMAIL" -xp ${SMTP_AUTH} -m `cat "$HTML_PATH_NAME"` 
                if [ "$?" -ne 0 ]
                then
                        while [ "$RETRY" -lt 3 ]        
                        do
                                sleep 2
                                /usr/bin/sendemail -f "${SMTP_EMAIL}" -u "$DATE ${GROUP_NAME}项目 日报请查收~" -s "${SMTP_SERVER}" -o tls=no -o message-content-type=html -o message-charset=utf8 -xu "${SMTP_EMAIL}" -t "$EMAIL" -xp ${SMTP_AUTH} -m `cat "$HTML_PATH_NAME"`
                                if [ "$?" -eq 0 ]
                                then
                                        break
                                else
                                        RETRY=$(($RETRY+1))
                                fi
                        done
                fi
        done
fi

find "$DATA_DIR" -type f -mtime +"$DATA_SAVE_TIME" -exec rm -f {} \;

image-20210413143518697

日报程序使用效果展示

image-20210413143639404

上面 时区不对 的问题。应该是我在 gitlab dashboard 中操作添加的 commit 导致的。我们不要 dashboard 添加一下 message 看看是否正确。

image-20210413144055456 再次执行一下这个脚本

1
./gitlogs.sh 

image-20210413145615142

可以看到是正常的

添加定时任务

1
2
3
4
5
crontab -e # 编辑 crontab 表
0 12 * * * /usr/bin/bash /data/scripts/gitlogs.sh >> /tmp/script_debug.log
0 16 * * * /usr/bin/bash /data/scripts/gitlogs.sh >> /tmp/script_debug.log
0 17 * * * /usr/bin/bash /data/scripts/gitlogs.sh >> /tmp/script_debug.log
0 19 * * * /usr/bin/bash /data/scripts/gitlogs.sh >> /tmp/script_debug.log