前言
這篇文章,很久很久之前就想寫了,但實際在寫的過程,發現涉及到2個玩意:
- git命令,比如git log
- gitlab ci的配置以及gitlab-ci.yml的基本使用
於是花費了不少時間來學習這些知識
如果你對上面這兩塊沒了解,建議你先看下下面三篇文章,先掃盲吧:
JB的git之旅--.gitlab-ci.yml介紹
JB的git之旅-git命令列
JB的git之旅-gitlab ci介紹
繼續往下讀,預設是對git log跟gitlab ci都瞭解了,並且相關環境已經配置好了;
開篇
做為一個久經沙場的測試同學,肯定會遇到下面這種場景:
專案經理/領導:JB,這BUG怎麼回事啊?(此時反饋BUG描述)
JB:我看看(同時趕緊確認BUG)
(幾分鐘後)
JB:這真的是有BUG,我看看怎麼回事(心裡描述,我去,昨天都沒問題的,怎麼就突然又有BUG了)
(一段時間過去了)
研發:這個BUG是因為昨晚JB2同學提交的程式碼導致的,現在已經修復了;
JB:???昨晚提交的程式碼?怎麼沒通知測試驗收?測試都不知道這回事啊~
複製程式碼
上面這種只是日常生活的冰山一角。。
研發:JB啊,我這有個優化,你來驗證一下;
JB:這個優化做了什麼,改動了什麼,有什麼影響面?
研發:這個就優化網頁響應速度,你可以對比下響應速度是不是更快了;沒什麼影響的,就如果真有問題,只會影響到開啟速度而已;
JB:那行,我驗證下速度是否有優化跟開啟網頁功能是否正常;
(一段時間後)
JB:OK,沒問題了,可以上線吧;
(上線後一段時間)
領導:JB,怎麼這裡會顯示不出東西?早上還是正常的啊;
後來確認,就是早上研發說的網頁速度優化導致的,但是這兩者沒有關係啊!尼瑪!
複製程式碼
生活中,研發偷偷上代碼或者研發修改後給出的影響面不足導致出現線上問題的情況是非常比較常見的,尤其在小公司裡面,常見的不得了;
那這類問題有沒有解決方案?
這個原因歸根到底是,個人認為是測試知道的太少了;
人都是不自覺的,如果一味依賴研發提供的資訊,假如某天研發說不清楚,又或者壓根沒有說,然後就直接上線了,怎麼破?
有同學可能會跳出來說,通過流程約束,這個方案是可行的,但是本次想介紹是利用工具來解決這問題;
因此就有了這麼一個想法:
獲取研發每一次提交的記錄,通過釘釘/郵箱通知對應的同學~
複製程式碼
這種做法能杜絕上面說的場景嗎?
答案肯定是否定的,但做了這個,至少測試同學有更多的資訊輸入,而不再是一問三不知,怎麼利用這些資訊,就要看具體的同學了~
效果圖
先貼一個效果圖,樣式就是:
XX推動到了專案名的XX分支
XX-提交記錄sha值+提交內容資訊
樣式為:
jb推動到了專案名的XX分支
jb-提交記錄sha值+提交內容資訊
功能介紹:
點選專案名可以跳轉到倉庫地址,點選分支名可以跳轉到倉庫的分支地址;
點選sha值,可以跳轉到對應提交記錄
任務拆解下,分成2塊:
1.獲取資料
2.釘釘通知
複製程式碼
釘釘通知
接入釘釘這塊,官網有文件,點選檢視即可;
連結裡面有交怎麼在釘釘上新建機器人,這裡不介紹了;
可以看到,釘釘支援以下型別:
文字型別
link型別
markdown型別
整體跳轉ActionCard型別
獨立跳轉ActionCard型別
FeedCard型別
複製程式碼
根據需要的結果,選擇不同型別吧,比如本文,選擇的是markdown型別
根據文件,直接上程式碼:
import requests
import json
dingdingurl = "你的釘釘機器人webhook"
#釘釘機器人的webhook
headers = {'Content-Type': 'application/json'}
String_textMsg = {
"msgtype": "markdown",
"markdown": {
"title" : "jbtest",
"text": "jb is here"
}
}
requests.packages.urllib3.disable_warnings()
String_textMsg = json.dumps(String_textMsg)
requests.post(dingdingurl, data=String_textMsg, headers=headers, verify=False)
複製程式碼
這裡的dingdingurl需要修改成你的機器人webhook,至於webhook怎麼獲取,看下上面的官網文件,都有介紹的,這裡不細說了;
上面的程式碼,執行後的效果就是這樣的了:
title對應的就是圖1釘釘顯示的標題,text就是點選進去後的內容,ok,釘釘接入就是如此的簡單~
程式碼的話,應該不需要說明了,就是根據釘釘的要求,構建請求頭,然後把對應資訊填入,發起post請求即可;
不過這裡可能有個疑問,下面這程式碼是幹嘛的?
requests.packages.urllib3.disable_warnings()
複製程式碼
之前的文件有介紹過,可以試試,註釋掉會怎樣:
InsecureRequestWarning: Unverified HTTPS request is being made.
Adding certificate verification is strongly advised.
複製程式碼
會報錯,但是不影響結果執行,這是一個安全警告提示,原因是我們在請求的時候,設定了, verify=False,意思是不校驗https;
在這個例子吧,把這個去掉依然是可以正常執行的,但是大部分涉及到https,都會進行校驗,為了除錯,就會加上verify=False;
這就是這麼一個由來~
git log獲取提交記錄
頂部git log的文章有提及到,git log裡面有一個pretty可以進行定製化,最終得出這麼一個命令:
git log --pretty=format:\"%an-%h-%s-%H\" -1
-1是表示最近一次提交,就是最新的提交記錄
複製程式碼
關於%an %h %s %H的含義,可以看下面,還有更多的欄位資訊,請移步到git log介紹吧~
選項 | 說明 |
---|---|
%an | 作者(author)的名字 |
%h | 提交物件的簡短雜湊字串 |
%s | 提交說明 |
%H | 提交物件(commit)的完整雜湊字串 |
最終的執行結果如下:
可能會有人問,為什麼我們要用這些引數?因為我們顯示的結果就是想要這些欄位;
根據上圖,我們需要以下資訊:作者名
倉庫名稱以及url
分支名稱以及url
提交物件的簡短的雜湊子串及url
提交說明
複製程式碼
上面git log已經獲得了3個引數了,那還剩下5個引數,通過其他方式獲取
.gitlab-ci.yml
來到這裡,預設是配置了runner,如果還是弄,從頂部的gitlab ci文章進去看看,裡面有介紹怎麼配置runner
按照要求,在專案首頁建立一個檔案:
.gitlab-ci.yml
複製程式碼
新建後,編輯這檔案,不難寫出下面的程式碼:
stages:
- test
job_test:
stage: test
variables:
branch_url: $CI_PROJECT_URL/tree/$CI_COMMIT_REF_NAME
commit_url: $CI_PROJECT_URL/commit/$CI_COMMIT_SHA
script:
- python getcommitlog.py $CI_PROJECT_URL $branch_url $CI_PROJECT_NAME $commit_url $CI_COMMIT_REF_NAME
only:
- master
複製程式碼
上面的程式碼,是根據JB的git之旅--.gitlab-ci.yml介紹這裡面的要求寫出的;
這裡再說明下:
定義一個stage,裡面包含一個叫test的階段;
然後定義個job_test任務,這個任務對應的就是一個叫test階段的stage;
然後建立兩個變數,分別是:branch_url跟commit_url,具體的值,就是不同變數的拼接;
建立完變數,就執行getcommitlog.py指令碼,並且傳一堆引數過去,最後設定只允許master分支執行;
複製程式碼
定義變數以及執行指令碼傳參時,涉及到幾個系統變數,含義如下:
變數 | 描述 |
---|---|
CI_PROJECT_URL | 訪問專案的HTTP地址 |
CI_COMMIT_REF_NAME | 構建專案的 branch 或 tag 名稱 |
CI_COMMIT_SHA | 構建專案的 commit SHA 值 |
CI_PROJECT_NAME | 當前正在構建的專案名稱(實際上是專案資料夾名) |
更多的系統變數,請看移步到JB的git之旅--.gitlab-ci.yml介紹檢視;
那自定義變數最終的含義是:
- branch_url:當然分支地址,比如http://xxxx/jb/jbtest/tree/master
- commit_url:提交記錄地址,比如http://xxxx/jb/jbtest/commit/對應的SHA
其他4個傳參的解釋如下,簡單說就是專案地址,專案名稱,提交分支名稱,commit 的SHA值
getcommitlog.py
介紹完.gitlab-ci.yml,那來介紹下里面呼叫的getcommitlog.py指令碼
該指令碼邏輯很簡單,
1)獲取git log資訊以及處理傳參資訊,
2)釘釘post,程式碼如下:
import re
import os
import requests
import json
import sys
def getContent():
#獲取提交記錄資訊
content = (os.popen("git log --pretty=format:\"%an-&%h-&%s\" -1 ").read()).split("-&")
return content
def postDingDing(content):
print(sys.argv)
project_url = sys.argv[1]
branch_url = sys.argv[2]
project_name = sys.argv[3]
commit_url = sys.argv[4]
branch_name = sys.argv[5]
name,shortcodenum,explain = content
dingdingurl = ["https://oapi.dingtalk.com/robot/send?access_token=你的機器人access_token"]
headers = {'Content-Type': 'application/json'}
String_textMsg = {
"msgtype": "markdown",
"markdown": {
"title" : "jbtest",
"text": "#### "+name+" 推送到了 ["+project_name+"]("+project_url+")"+" 的["+branch_name+"]("+branch_url+") 分支\n>"
+name+" -["+shortcodenum+"]("+commit_url+")"+" "+explain
}
}
requests.packages.urllib3.disable_warnings()
String_textMsg = json.dumps(String_textMsg)
for i in dingdingurl:
requests.post(i, data=String_textMsg, headers=headers, verify=False)
print(name,shortcodenum,explain,project_url,branch_url,project_name,commit_url,branch_name)
if __name__ == "__main__":
content = getContent()
postDingDing(content)
複製程式碼
指令碼很簡單,
1)就是獲取git log所需要的值,
2)就是獲取傳過來的引數,
3)字串拼接,
4)釘釘post通知,
這部分不打算介紹了,很簡單的程式碼;
至此,整個功能介紹完畢了,把.gitlab-ci.yml
放到倉庫根目錄,getcommitlog.py
自定義目錄,只不過.gitlab-ci.yml上也要跟著改下路徑,然後提交兩個檔案,在master分支改下程式碼提交,就釘釘就可以收到資訊了,如果不想指定master分支,就把only master去掉;
除了釘釘可以收到通知,gitlab ci上也可以看到執行情況,在倉庫-CI/CD-jobs,就能看到所有.gitlab-ci的執行情況
題外話
有同學可能會問,如果有一個指令碼,比如上面這個,想所有倉庫低使用,那豈不是每個倉庫都要上傳這兩個檔案?
答對一部分,.gitlab-ci.yml
是每個倉庫都需要,但是執行的指令碼,可以共用,怎麼公用?
通過.gitlab-ci.yml
裡面的指定執行路徑即可;
比如倉庫A有指令碼A,如果想讓倉庫B也使用指令碼A,那可以在倉庫B的.gitlab-ci.yml
檔案裡面執行執行倉庫A的指令碼A,使用絕對路徑,如果沒有許可權,給許可權即可;
比如一開始gitrunner安裝目錄在/home上,那執行倉庫A的時候,就會在runner伺服器有一個目錄:
這個檔案只要不刪除,都會存在,但是需要注意的,不建議直接hardcode路徑,因為builds後面的13c1a0f2
感覺是個編號,會變化的,通過正則判斷倉庫即可;
從此在釘釘上就知道研發提交了什麼,點選倉庫地址還能看到研發寫了什麼(前提是你得有倉庫許可權),給研發review程式碼不再話下,想想帶心動了~
介紹就到這裡,程式碼上面有,這裡不重複貼了,就是需要2個檔案而已;小結
本文主要介紹通過gitlab ci獲取提交記錄,涉及到git log已經gitlab ci.yml的語法以及釘釘介面推送的使用,都是基礎知識點,在配置gitlab ci會容易出現問題,無太高難度的事情;
謝謝大家~