在一個共享項目(或者說多人協同開發的項目)的開發過程當中,爲有效確保團隊成員編碼風格的統一,確保部署方式的統一,等等(git的用戶常常會涉及到此類場景),經常會使用相似 Git Flow 這種比較複雜的工做流開發模式。在較大型的項目中,雖然這種工做流模式比較成熟,但在分支處理方面,這種工做流就會形成較多的重複勞動。html
所以,若是能借助某些工具來自動化處理這些重複性事務,好比自動合併分支,那麼對於提高咱們的工做效率,將會有很大的幫助。git
本文將從如下三種方法對自動化任務處理作介紹,並對每一種方法的優缺點作個簡單的總結,以及在實際工做中咱們該如何作出選擇。github
Git hooks是基於事件的。當你執行特定的git指令時,該軟件會從git倉庫下的hooks目錄下檢查是否有相對應的腳本,若是有就執行。web
有些腳本是在動做執行以前被執行的,這種「先行腳本」可用於實現代碼規範的統1、完整性檢查、環境搭建等功能。有些腳本則在事件以後被執行,這種「後行腳本」可用於實現代碼的部署、權限錯誤糾正(git在這方面的功能有點欠缺)等功能。docker
鉤子都被存儲在Git目錄下的hooks子目錄中。也即絕大部分項目中的.git/hooks。當你用git init初始化一個新版本庫時,Git 默認會在這個目錄中放置一些示例腳本。這些腳本除了自己能夠被調用外,它們還暴露了被觸發時所傳入的參數。這些示例的名字都是以 .sample 結尾,若是想啓用它們,移除這個後綴便可。shell
把一個正確命名且可執行的文件放入 Git 目錄下的 hooks 子目錄中,便可激活該鉤子腳本。這樣一來,它就能 被 Git 調用。vim
git hooks 採用 事件機制, 在相應的操做(好比 git commit / git merge)下觸發, 分爲 2 種:segmentfault
服務端 hooks, github 的 webhooks 就是在此基礎上創建起來的;bash
客戶端 hooks, 每一個 git 版本庫的 .git/hooks/ 文件夾下就有可使用的例子。服務器
注意: 客戶端 hooks 並不會同步到版本庫中
客戶端鉤子由諸如提交和合並這樣的操做所調用,而服務器端鉤子做用於諸如接收被推送的提交這樣的聯網操做。
客戶端鉤子位於項目根目錄 your_project/.git/hooks 文件夾下
服務端鉤子則位於 your_project.git 文件夾下的 hooks 和 custom_hooks
能夠看到GitLab爲咱們建立了一個軟鏈接鏈接到了GitLab自定義的鉤子目錄,這樣全部建立的項目均可以使用同一個腳本規則,減小了維護成本。
那咱們如何結合GitLab定製本身的腳本呢?git會首先觸發GitLab的腳本,而後GitLab執行完本身的腳本文件後會再調用掉用戶放在custom_hooks下的腳本,因此咱們只須要將咱們定製好的腳本放在custom_hooks下便可,腳本名稱和以前同樣。例如:touch post-receive,這個腳本理論上可使用任何腳本語言例如Perl、Python、Ruby等,不過執行這個腳本的用戶將是git,要注意git用戶對系統的操做權限,還要注意post-receive這個腳本須要可以有執行權限。
將目錄切換至 ../BRIDGE_REPO.git/hooks,用 cp post-receive.sample post-receive 複製並重命名文件後用 vim post-receive 修改。其內容大體以下:
#!/bin/sh unset GIT_DIR NowPath=`pwd` DeployPath="../../www" cd $DeployPath git pull origin master cd $NowPath exit 0
使用 chmod +x post-receive 改變一下權限便可,服務器端的配置就基本完成了。
要了解GitLab-CI與GitLab Runner,咱們得先了解持續集成是什麼。
持續集成是一種軟件開發實踐,即團隊開發成員常常集成他們的工做,一般每一個成員天天至少集成一次,也就意味着天天可能會發生屢次集成。每次集成都經過自動化的構建(包括編譯,發佈,自動化測試)來驗證,從而儘快地發現集成錯誤。許多團隊發現這個過程能夠大大減小集成的問題,讓團隊可以更快的開發內聚的軟件。
GitLab-CI就是一套配合GitLab使用的持續集成系統(固然,還有其它的持續集成系統,一樣能夠配合GitLab使用,好比接下來要說的Jenkins)。
持續集成,咱們一般使用CI來作一些自動化工做,好比程序的打包,單元測試,部署等,這種構建方式避免了打包環境差別引發的錯誤,提升了工做效率。Gitlab-CI是Gitlab官方提供的持續集成服務,咱們能夠在倉庫的根目錄下新建.gitlab-ci.yml文件,本身定義持續集成流程模板,而且在Gitlab中配置runner,在以後的每次提交或合併中將會觸發構建,而且能夠經過Gitlab的hook, 在代碼提交的各個環節自動地完成一系列的構建工做,總之對於一些非複雜性的集成需求,都是能夠知足的。
實際上,GitLab-CI中有一個概念叫 Pipeline ,一次 Pipeline 其實至關於一次構建任務,裏面能夠包含多個流程,如安裝依賴、運行測試、編譯、部署測試服務器、部署生產服務器等流程。任何提交或者 Merge Request 的合併均可以觸發 Pipeline。
思考:
爲何不是 GitLab CI 來運行那些構建任務?
通常來講,構建任務都會佔用不少的系統資源 (譬如編譯代碼),而 GitLab CI 又是 GitLab 的一部分,若是由 GitLab CI 來運行構建任務的話,在執行構建任務的時候,GitLab 的性能會大幅降低。
GitLab CI 最大的做用是管理各個項目的構建狀態,所以,運行構建任務這種浪費資源的事情就交給 GitLab Runner 來作了!
由於 GitLab Runner 能夠安裝到不一樣的機器上,因此在構建任務運行期間並不會影響到 GitLab 的性能~
GitLab-Runner是配合GitLab-CI進行使用的。通常地,GitLab裏面的每個工程都會定義一個屬於這個工程的軟件集成腳本,用來自動化地完成一些軟件集成工做。當這個工程的倉庫代碼發生變更時,好比有人push了代碼,GitLab就會將這個變更通知GitLab-CI。這時GitLab-CI會找出與這個工程相關聯的Runner,並通知這些Runner把代碼更新到本地並執行預約義好的執行腳本。
因此,GitLab-Runner就是一個用來執行軟件集成腳本的東西。你能夠想象一下:Runner就像一個個的工人,而GitLab-CI就是這些工人的一個管理中心,全部工人都要在GitLab-CI裏面登記註冊,而且代表本身是爲哪一個工程服務的。當相應的工程發生變化時,GitLab-CI就會通知相應的工人執行軟件集成腳本。
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/ci):
http://xxxxxx // 在這裏輸入gitlab安裝的服務器ip/ci 便可
Please enter the gitlab-ci token for this runner:
xxxxxxxxxxxxxxxxxx // 這裏的token可經過Gitlab上的項目Runners選項查看
Please enter the gitlab-ci description for this runner:[E5]:demo
// 這裏填寫一個描述信息
Please enter the gitlab-ci tags for this runner (comma separated):
demo // 在這裏填寫tag信息,多個tag可經過逗號,分割。
tag:一個項目可能有多個runner,是根據tag來區別runner的。
Registering runner... succeeded. runner=eaYyokc5
Please enter the executor: docker, docker-ssh, parallels, shell, ssh, virtualbox, docker+machine, docker-ssh+machine:
shell // 在這裏須要輸入runner的執行方式,直接輸入shell
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded! // 出現這樣信息表示服務端的配置就已經成功結束了。
若是你在項目倉庫裏面加入.gitlab-ci.yml文件,同時給項目配置了gitlab-runner, 那麼每次提交代碼或者合併 mr , 都會觸發你的 CI Pipeline (持續集成管道)。
stages: - deploy deploy: stage: deploy script: - echo "start deploy....." - deploy only: - master tags: - shell
其中deploy是編寫的shell腳本,能夠實現將要發佈的內容自動部署到發佈目錄下:
#!/bin/bash deploy_path="xxx" project_path="xxx; judge_path = "$deploy_path/$project_path" if [ ! -d "$judge_path" ] then project_url="xxx.git" git clone $project_path $deploy_path else cd $deploy_path git pull fi
gitlab ci/cd .gitlab-ci.yml配置詳解
Webhooks 容許第三方應用監聽 GitLab 上的特定事件,在這些事件發生時經過 HTTP POST 方式通知( 超時5秒) 到第三方應用指定的 Web URL。 例如項目有新的內容 Push,或是 Merge Request 有更新等。 WebHooks 可方便用戶實現自動部署,自動測試,自動打包,監控項目變化等。
webhooks, 能夠在 pull request / merge master 等幾個場景下, 設置異步回調通知(http 請求)。這個背後就是 git hooks 在起做用。
所以,利用 WebHooks 的特性,可配合 Jenkins 實現一系列的自動化任務。
Jenkins是一個用Java編寫的開源的持續集成工具,能夠與Git打通,監聽Git的merge, push事件,觸發執行Jenkins的指定任務(job)。例如發佈的任何一個環節均可自動完成,無需太多的人工干預,有利於減小重複過程以節省時間和工做量等。
#!/bin/sh echo *****************Start***************** date # 獲取最近一次提交的 commit id sha1=`git rev-parse HEAD` # 獲取姓名及郵箱,來配置git提交者信息 name=`git show $sha1 | grep 'Author:' | cut -d' ' -f2` email=`git show $sha1 | grep 'Author:' | cut -d' ' -f3 | sed -e 's/<//g' | sed -e 's/>//g'` echo '當前提交人信息:' echo $name echo $email git config --global user.name $name git config --global user.email $email echo '***************** git checkout develop & git pull:' git checkout develop git pull # develop合併master echo '***************** git merge origin/master:' conflict=`git merge origin/master` echo $conflict | grep 'CONFLICT' if [ $? -ne 0 ]; then echo '***************** git push origin HEAD:' git push origin HEAD echo '***************** git status:' git status else git status echo 'Automatic merge failed...' echo 'Please fix conflicts and then commit the result...' exit 1 fi echo *****************End*****************