Learn More →
如果希望在git生命週期中,在本機增加一些CI[1]任務的話,或許可以不必特地架一台CI Server[2]去處理,只需要使用到本篇的主角「Git Hook」,就可以達到基本的CI任務了。
Git提供的一組客製化條件觸發腳本的規則,統稱這個規則為Git Hook。這些規則適用於Git的幾個重要操作環節,例如: 提交(commit)、合併(merge)等[3]。
在講求快速開發的時代,軟體提交的數量也隨之大量增加。若還是寄望所有的CI工作都交由CI Server來處理,那很快就會面臨到機器效能不足的嚴峻議題。另一方面,組織也希望減少在CI上的成本,同時又期許軟體產出的品質提升。事實上,我認為「許多的CI工作,是可以分派給開發人員自己負責,而不是完全將其推卸給其它人或機器」。Git Hook則是我認為目前在現代開發模式中,最適合拿來利用、推廣的一項工具。
一般來說,Git在初始化專案的時候,會自動產生一組Git Hook範例腳本,並將其存放在.git/hooks/
底下。幸運的話可以在.git/hooks/
底下看到下面這些範例Git Hook腳本:
applypatch-msg.sample pre-applypatch.sample pre-rebase.sample
commit-msg.sample pre-commit.sample pre-receive.sample
fsmonitor-watchman.sample pre-merge-commit.sample prepare-commit-msg.sample
post-update.sample pre-push.sample update.sample
對Git而言,僅會認hooks底下符合這些命名規範的檔案名稱,且不需要任何副檔名。所以這些腳本預設是關閉的,如果要啟用它們,僅需要重新命名將.sample
移除即可。如果要固定使用同一組Git Hook腳本,可以透過core.hooksPath
來指向執行Git Hook的目錄[4]。
git init
初始化的資料夾當中,會出現這些範例Git Hook腳本。這其實是因為.git/
內的檔案,並不會被Git主動納入版本控管。
pre-commit
讓顯示訊息一致案例描述 :
因為會在不同的電腦、工具中,對相同專案使用Commit紀錄修改,有時候會忘記自己使用哪個名字、信箱,所以時常導致在同一個專案出現多名角色。
解決方法[5] :
利用簡單的Shell Script判斷使用者資訊,沒有設定好就不給Commit。
#!/bin/sh
username=$(git config user.name)
if [ "$username" != "LAI, CHUN JING" ]
then
cat <<\EOF
[ERROR] Are you LAI, CHUN JING?"
EOF
exit 1
fi
pre-push
觸發執行回歸測試案例描述 :
因為專案的急迫性,有時候開發完新功能或是修改完BUG後,就會急急忙忙地將程式推上版。但是,若是組織沒有一個完善的CI Server,且自己也忘記在推版前執行測試案例,去確認原有功能在修改後是否保持完整,那很可能就會不小心推了一版「改A壞B」的程式上去。
解決方法[6] :
#!/bin/sh
echo "Running mvn clean test for errors"
DIR=`pwd`
CWD="$DIR/app_example"
MAIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $CWD
MVN_RESULT=$(mvn clean test 2>&1)
if [ $? -ne 0 ]; then
echo
echo "${MVN_RESULT}" | ((tee /dev/fd/5 | grep -A 10 -B 2 "Reactor Summary:" >/dev/fd/4) 5>&1 | sed -n -e '/^Failed tests:/,/Tests run:.*$/ p' ) 4>&1
echo
echo "Error while testing the code"
cd $CWD
exit 1
fi
若是出現這個訊息,代表commiter並沒有執行.git/hooks/
的權限,這時就可以使用chmod ug+x .git/hooks/*
這行指令,給予使用者及群組擁有執行(x)
的權限。