寫代碼的時候,git push到遠程代碼庫后,往往還要連到服務器上pull代碼才能進行測試。代碼push后自動更新測試服務器的代碼也算是一種剛需了。
gitLab的鈎子分為兩大類:1.web hooks
2.custom hooks,這是調用git原生鈎子,這里的鈎子也有兩種類型:(1)全局鈎子 (2)每個項目對應的鈎子。
這幾天踩了很多坑,才用一種迂回的方法解決了問題。介紹一下GitLab和ubuntu的版本:Ubuntu 16.04.1 LTS + GitLab Community Edition 9.4.4 和 GitLab Community Edition 8.15.4,兩個版本的gitlab配置起來是幾乎是一樣的。
1.web hooks
官方文檔:https://docs.gitlab.com/ee/user/project/integrations/webhooks.html
這里就不重點介紹了,主要介紹讓我踩了很多坑的custom hooks
2. custom hooks
官方文檔:https://docs.gitlab.com/ee/administration/custom_hooks.html#custom-git-hooks
這里的官網文檔有句:Normally, Git hooks are placed in the repository or project's hooks
directory. GitLab creates a symlink from each project's hooks
directory to the gitlab-shell hooks
directory for ease of maintenance between gitlab-shell upgrades.
這里的symlink是軟鏈接,類似windows的快捷方式,但是還是有區別:以gitlab中的hooks目錄為例:
在dir1/hooks/A,在dir2/hooks/A,這里兩個hooks是軟鏈接的關系,其實是同一個。路徑dir1和dir2不同,但是對這兩個目錄下的hooks目錄的文件修改,添加,刪除,都同時起作用,因為這個目錄本來就是一個。好了,我們看gitlab中是怎樣做的:
(1)/opt/gitlab/embedded/service/gitlab-shell/hooks
(2)/var/opt/gitlab/git-data/repositories/root/Test.git/
官方文檔指出:For Omnibus installs the path is usually /var/opt/gitlab/git-data/repositories/<group>/<project>.git
每個組用戶,對應項目下有個hooks文件夾,這個文件夾和(1)中的是同一個文件夾,這里采用的是軟鏈接方式,雖然路徑不同,其實他們指向的是同一個文件夾。
這個hooks文件(以下說的hooks目錄都是指上面2個路徑的目錄,他們是軟鏈接關系,其實只有一個實體),有三個文件post-receive,update和pre-receive鈎子,這是服務器鈎子(git也有服務器鈎子和客戶端鈎子,gitLab類似)。
當客戶端push之后,服務器會鈎子會觸發,其中就有這個post-receive,實現自動更新,就需要在這個post-receive鈎子的時候,執行一些腳本操作。這個hooks文件夾里的鈎子是全局鈎子,我們需要的是每個項目自定義的鈎子。
按照官方的文檔說明的步驟 https://docs.gitlab.com/ee/administration/custom_hooks.html#custom-git-hooks
簡而言之,就是在/var/opt/gitlab/git-data/repositories/<group>/<project>.git目錄下建立一個custom_hooks的目錄,這個目錄下放文件名符合鈎子規范的鈎子,比如post-receive,update, pre-receive等,注意沒有后綴名。還有就是需要修改權限,讓他們可以執行,並且保證這個目錄和目錄下的文件的所有權屬於git用戶。可以參考:http://blog.hgomez.net/2015/03/02/Gitlab-custom-hooks-Bash-Way.html
但是奇怪的是,我安裝這個步驟仔細檢查和修改了幾遍,就是沒有生效,感覺是哪里出了問題,這個每個工程自定義的鈎子好像不能被gitLab調用一樣。看了hooks文件夾下的post-receive才有了思路,雖然這個是ruby語言編寫的,看這行:
感覺是先new一個全局鈎子,進行調用,然后再new一個custom_hooks進行調用,原來是我之前把原版的ruby版的post-receive鈎子屏蔽了,直接用shell寫了個post-receive鈎子,放在hooks目錄下了,當然就不去調用custom_hooks目錄下的鈎子了,官方文檔貌似沒對這說明。
不同版本的gitLab,if后面的函數參數可能不同,這里有GitlabCustomHook,還有那個頭文件gitlab_custom_hook,去看看這個頭文件里面有什么。
61-65的注釋已經顯示了查找鈎子的目錄,第71行和第75行,可以看出custom_hooks這個文件夾的的名稱已經是寫死的,第78行的注釋可以看出,gitlab的配置文件中,custom_hook_dir項不設置的話,就會直接在hooks目錄下查找全局鈎子。gitlab的配置文件目錄/etc/gitlab/gitlab.rb
這里就沒必要設置這個,順便說一句,改了這個配置文件后,需要gitlab-ctl reconfigure之后才能生效(會重新編譯,重起服務,還有會覆蓋每個工程下面的自動配置文件)。
弄清楚了這些,就可以在需要自定義鈎子的目錄下自己建立一個custom_hooks鈎子
查看文件夾的擁有者是誰,查看文件夾的命令是:ls -ld custom_hooks/
會看到擁有者是當前終端登陸的用戶,修改為git擁有者的命令是: chown -R git:git custom_hooks/
進入custom_hooks文件夾,建立我們需要的鈎子post-receive,沒有后綴名,修改擁有者為git:chown -R git:git post-receive, 修改權限:chmod 755 post-receive
測試./post-receive是否可執行。
3.測試鈎子是否被執行
(1)在ubuntu上的測試方法:直接在終端上用命令行來測試:
在客戶端建立一個空目錄,git init,然后git clone 地址,這樣就可以clone一個分支了,然后修改這個里面的文件,比如README文件,git commit -a,添加注釋等,最后是git push
注意,這時在服務器端全局鈎子hooks目錄下的post-receive就會被調用(這個文件可以是shell腳本,在里面echo "global post-receive ------------------>"),這樣的話,如果正常,在客戶端的git bash或者客戶端的終端中,就會看到這句提示了。這種方法就可以驗證服務器端鈎子有沒有執行。
(2)在windows上的測試方法:建議不要用圖像話的工具,比如SmartGit,直接用git bash命令行,好處是服務器端的鈎子執行了,如果有提示輸出,會直接在命令行中顯示remote:******** 如果采用SmartGit這樣的圖形化節目,可能就看不到這樣的輸出了。