一、用到的工具
- Gitlab
- Jenkins
- Shell
- go test
二、實作原理
在gitlab上配置jenkins的webhook,當有代碼變更時自動觸發jenkins建構job,job内的shell腳本負責把覆寫率報告以釘釘群通知的方法發送出去。
三、Jenkins job配置
點選上圖中的“進階”,出現下圖後,點選“Generate”,生成Secret token。
四、Gitlab配置webhook
五、Shell腳本
touch last_num.txt
fi
#存儲本次.go檔案和_test.go檔案的個數,作為上次資料
echo $this_time_go_num > ./this_time_go_num.txt
echo $this_time_test_go_num > ./this_time_test_go_num.txt
echo $this_time_per > ./this_time_per.txt
#擷取上次的.go檔案數,如果沒有則建立檔案
if test -e last_time_go_num.txt
then
last_time_go_num=$(cat last_time_go_num.txt)
echo $last_time_go_num
else
touch last_time_go_num.txt
#擷取上次的test.go檔案數,如果沒有則建立檔案
if test -e last_time_test_go_num.txt
last_time_test_go_num=$(cat last_time_test_go_num.txt)
echo $last_time_test_go_num
touch last_time_test_go_num.txt
#擷取上次的per,如果沒有則建立檔案
if test -e last_time_per.txt
last_time_per=$(cat last_time_per.txt)
echo $last_time_per
touch last_time_per.txt
#計算兩次.go檔案數的差
go_num_diff=`expr $this_time_go_num - $last_time_go_num`
echo $go_num_diff
#計算兩次test.go檔案數的差
test_go_num_diff=`expr $this_time_test_go_num - $last_time_test_go_num`
echo $test_go_num_diff
#計算兩次占比的差
this_time_test_go_num_init=$(printf "%d" $(($this_time_test_go_num*100/$this_time_go_num)))
last_time_test_go_num_init=$(printf "%d" $(($last_time_test_go_num*100/$last_time_go_num)))
per_diff=$(printf "%d%%\n" $(($this_time_test_go_num_init-$last_time_test_go_num_init)))
echo $per_diff
cd -
echo "生成Html報告"
go tool cover -html=cover.out -o coverage.html
cp coverage.html /Users/xes/CI/reports/xxx-unitcover/a_this_time_html_report/this_time_coverage.html
# 構造知音樓通知text的内容
cd $this_path
this_time=$(cat this_num.txt)
last_time=$(cat last_num.txt)
now=$(echo $this_time|cut -b 1,2,3,4)
last=$(echo $last_time|cut -b 1,2,3,4)
change=$(echo | awk "{print $now - $last}")
# 設定secret
secret=""
# 設定Webhook
xxx_robot_path=
access_token=
# URL Encode 函數
function urlencode() {
local LANG=C
local length="${#1}"
i=0
while :
do
[ $length -gt $i ]&&{
local c="${1:$i:1}"
case $c in
[a-zA-Z0-9.~_-]) printf "$c" ;;
*) printf '%%%02X' "'$c" ;;
esac
}||break
let i++
done
}
# 執行函數
function run() {
# 擷取時間戳
cur_sec_and_ns=`date '+%s-%N'`
cur_sec=${cur_sec_and_ns%-*}
cur_ns=${cur_sec_and_ns##*-}
cur_timestamp=$((cur_sec*1000+cur_ns/1000000))
echo "目前時間戳:"$cur_timestamp
# 獲得簽名
sign=`echo -n -e "$cur_timestamp\n$secret" | openssl dgst -sha256 -hmac $secret -binary | base64`
echo "加密後簽名:"$sign
# 對簽名進行 urlencode
sign_urlencode=`urlencode $sign`
echo "urlencode 後簽名:"$sign_urlencode
url_action=""
url_encode=`urlencode $url_action`
echo $url_encode
request_url=$yach_robot_path"×tamp="$cur_timestamp"&sign="$sign_urlencode
echo "最終請求的 URL:"$request_url
curl -X POST \
$request_url \
-H 'content-type: application/json' \
-d '{
"msgtype": "action_card",
"action_card": {
"title": "單測統計xxx",
"markdown": "### *_test.go占比(不含vendor) \n| 統計----------- | 本次------ | 上次------ | 新增 | \n| :--- | :--- | :--- | :--- | \n| .go | '"$this_time_go_num"' | '"$last_time_go_num"' | '"$go_num_diff"' | \n| test.go | '"$this_time_test_go_num"' | '"$last_time_test_go_num"' | '"$test_go_num_diff"' | \n| test.go/.go | '"$this_time_per"' | '"$last_time_per"' | '"$per_diff"' | \n### *_test.go覆寫率(平均值) \n| 本次------ | 上次------ | 內插補點 | \n| :--- | :--- | :--- | \n| '"$this_time"' | '"$last_time"'| '"$change"' | \n \n#### 本次&上次覆寫率HTML報告(點選打開) \n'"$url_action"'",
"image": "https://sentry.io/_assets/screenshots/features-page-dash-12c65431808e7d8daf234a096446c1f0da311a0f3bcec5352e28bda60136fb16.jpg",
"content_title": "xxx單測覆寫率統計",
"single_title": "點選此處,在側邊欄檢視HTML報告",
"single_url": ""
}
}'
run
#把本次的覆寫率指派給上次
cp this_num.txt last_num.txt
#把本次的.go檔案值給上次
cp this_time_go_num.txt last_time_go_num.txt
#把本次的test.go檔案值給上次
cp this_time_test_go_num.txt last_time_test_go_num.txt
#把本次的per值給上次
cp this_time_per.txt last_time_per.txt
#用本次的HTML報告覆寫上次的HTML報告
cd ..
cp a_this_time_html_report/this_time_coverage.html b_last_time_html_report/last_time_coverage.html
避坑:
在slave機器上git clone遇到一個小坑,如下圖:
原因是slave機器上的git預設賬号對此gitlab倉庫權限不足,解決方法是給git clone指令加上username和password
六、Go test 指令
如步驟五中所示,用到2個go test指令,如下:
go test ./... -coverprofile=cover.out # 生成.out檔案
go tool cover -html=cover.out -o coverage.html # 生成Html報告
七、釘釘群通知
釘釘機器人配置:
釘釘機器人的安全設定方式有3種,我們這裡選擇方式一“自定義關鍵詞”
添加釘釘機器人:
請求字段說明:
注意:請求的content中(content即link的值,也就是在text或title中包含)必須包含釘釘機器人的“自定義關鍵詞”,比如我們curl請求中就包含了“單元測試”,否則會報如下圖的錯誤
八、通知消息展示
釘釘群接收到的通知消息: