目前公司的前端資源託管在svn服務器上,因爲團隊的逐漸擴大,svn的分支管控愈來愈不靈活,並且對於之後前端流程一體化的處理支持不是很好,所以決定在版本控制上轉向git。git的好處不用多說:多分支並行開發,自動化構建,持續集成等等,這也是促使咱們轉向它的緣由。php
首先嚐試使用gitlab提供的web hooks進行觸發腳本控制。web hooks發出的post請求咱們的php文件,在php中執行相關shell腳本,完成一體化構建。可是shell中的提示輸出信息沒法在本地進行顯示,所以即便項目構建失敗,開發人員並沒有法在git命令行獲得直觀的提示,用戶交互很不友好。經測試,只有放在remote端的hooks目錄下的腳本輸出信息才能呈如今終端,所以最終放棄此種方案。
gitlab提供的web hooks的底層實現-update.rb的邏輯是基於remote端的update hook。update hook 會在用戶每次push到remote時觸發,根據返回值是否爲0,來決定這次push是否成功,它接收3個參數,第一個位push的引用分支名,第二個爲push以前的分支sha1,第三個爲push以後的sha1。update.rb封裝了提供了web hooks的功能,默認經過http post請求訪問咱們的服務端,而後執行服務端的命令。最後,更新web界面。
其次把目光轉移到remote端的hooks目錄,將咱們的update腳本放入hooks中,可是問題來了,因爲gitlab提供的web hooks觸發也是基於update腳本,並且該update腳本軟鏈接到一個ruby腳本(全部的gitlab項目共用同一個ruby腳本),所以,沒法針對前端工程制定特有的發佈流程,只有手動將全部的前端工程軟連接到一個ruby腳本的副本(update_f2e),在這裏作法就有點曲折:
1,首先,咱們在update_f2e這個ruby中先執行原有的邏輯,最後執行咱們本身寫的update(shell腳本),可是問題在於在update(shell腳本)中沒法接收update_f2e傳入的參數,並且update(shell腳本)中的提示信息也沒法顯示在終端,用戶體驗差,放棄;
2,而後針對調用流程從新構建,腳本所有ruby化。將咱們的shell腳本的邏輯修改成ruby,在update_f2e中執行,問題仍然是輸出信息沒法顯示,放棄;
3,究極版,將update_f2e這個ruby文件修改成shell腳本,在咱們的shell腳本執行完畢以後,經過命令行執行原有的ruby邏輯,最終,目的達成。
說了這麼多,嘗試了接近幾百次push,終於採用shell->ruby的方式完成hook的無害觸發,實現構建發佈。前端
最後,方法3的方法有一個弊端,就是服務端的代碼更新成功,但gitlab的web界面卻沒法更新,經過排查gitlab的ruby源碼,發現是在gitlab-shell/lib/gitlab_update.rb中的 api.allowed?()執行失敗形成,進一步深刻gitlab_net.rb中,發現是咱們的當前目錄影響了api.allowed?方法的判斷,所以在hooks/update的shell中切換到合適目錄以後,解決了該問題。git