Gitlab 是不錯(cuò)的代碼托管工具闯估,最近一年更新也很頻繁憔四。最新的 8.15 版本加入了自定義 git hook 的支持旬昭,在服務(wù)器端寫腳本控制用戶的提交情況變得很方便旧噪。這里介紹如何配置服務(wù)器端 hook。
Gitlab custom hook 官方文檔在此: Custom Git Hooks - GitLab Documentation
Tips: Git hook 是 git 提供的特定工作流事件自動(dòng)觸發(fā)腳本機(jī)制,本文介紹的是配置所有項(xiàng)目通用的 server hook赦抖,如果要使用 local hook舱卡,建議使用 git template + 軟鏈接解決分發(fā)和更新的問題。
具體步驟
1. 修改 gitlab 配置 vi /etc/gitlab/gitlab.rb
队萤,增加 custom_hooks_dir 路徑:
gitlab_shell['custom_hooks_dir'] = "<custom_hooks_dir>"
2. 執(zhí)行 sudo gitlab-ctl reconfigure
Tips:不要嘗試直接修改
<gitlab-shell>/config.yml
的文件內(nèi)容轮锥,文件中有說明:
This file is managed by gitlab-ctl. Manual changes will be erased! To change the contents below, edit /etc/gitlab/gitlab.rb and runsudo gitlab-ctl reconfigure
.
3. 創(chuàng)建 hook 文件
自定義腳本目錄要符合 <custom_hooks_dir>/<hook_name.d>/*
的規(guī)范。具體來說就是:
- 在自定的
custom_hooks_dir
目錄下可創(chuàng)建三個(gè)文件夾對(duì)應(yīng)三類server hook name
:- pre-receive.d
- update.d
- post-receive.d
- 在每個(gè)文件夾下可創(chuàng)建任意文件要尔,在對(duì)應(yīng)的 hook 時(shí)期舍杜,gitlab 就會(huì)主動(dòng)調(diào)用
- 文件名以
~
結(jié)尾的文件會(huì)被忽略 - 如果想看這部分的實(shí)現(xiàn)細(xì)節(jié)可以看
<gitlab-shell>/lib/gitlab_custom_hook.rb
文件
目錄結(jié)構(gòu)示意:
[root@localhost custom_hooks]# tree
.
├── post-receive.d
│ ├── 01.sh
│ └── 02.sh~
├── pre-receive.d
│ ├── 01.sh
│ ├── 02.py
│ └── 03.rb
└── update.d
├── 01.sh
└── 02.sh
4. 編寫 hook 腳本
Hook 腳本就是 git 自身的規(guī)范,寫 shell赵辕、python既绩、ruby 都可以。
留意腳本最后的退出值:0 正常退出还惠,用戶可以 push熬词;非 0 異常退出,中斷提交(pre-receive 和 update) 吸重。
細(xì)節(jié)參見: 5.4 Git鉤子:自定義你的工作流 · geeeeeeeeek/git-recipes Wiki · GitHub
如果想讓用戶 push 時(shí)看到相應(yīng)的日志直接在腳本中 echo 即可互拾。
這里舉兩個(gè)例子:
??:Say hi.
#!/bin/sh
echo "Say hi from gitlab server. ??"
exit 0
??:檢查提交修改的文件,發(fā)現(xiàn)有特定內(nèi)容禁止提交
#!/bin/sh
FIND_KEY='.test.51offer.com'
OLD_VALUE=$2
NEW_VALUE=$3
FILES=$(git rev-list --objects $OLD_VALUE...$NEW_VALUE | egrep '\.(jsp|vm|java)$' | awk '{print $2}' | sort | uniq )
FLAG=0
for FILE in $FILES
do
git show $NEW_VALUE:$FILE | grep -q "$FIND_KEY"
if [ $? -eq 0 ]
then
FLAG=1
echo "?? 包含非法字段 '$FIND_KEY' : $FILE"
fi
done
if [ $FLAG -eq 0 ]
then
echo "? 代碼檢查通過."
else
echo "? 代碼檢查不通過!"
exit 1
fi
exit 0
4. Enjoy!
上面第二個(gè)例子中嚎幸,嘗試 git push
颜矿,就能看到如下的日志:
Pushing to git@gitlab.51offer.inner:mall/paycenter.git
remote: ?? 包含非法字段 '.test.51offer.com' : service/src/main/java/com/horizon/module/paycenter/service/PayService.java
remote: ? 代碼檢查不通過!
remote: error: hook declined to update refs/heads/test
To git@gitlab.51offer.inner:mall/paycenter.git
= [up to date] release/old -> release/old
= [up to date] v1.0.0.2016.9.8 -> v1.0.0.2016.9.8
! [remote rejected] test -> test (hook declined)
error: failed to push some refs to 'git@gitlab.51offer.inner:mall/paycenter.git'
Completed with errors, see above
總結(jié):
Gitlab 官方對(duì)配置細(xì)節(jié)的表達(dá)并不清楚,配置過程中走了些彎路嫉晶,翻了翻源碼才摸索成功骑疆。 在此記錄下來,過程并不算繁瑣替废。
其實(shí)在 8.15 之前的版本通過修改 <gitlab-shell> 下的 hook 文件也能達(dá)到自定義 hook 的目的箍铭,不過升級(jí)版本可能會(huì)被沖掉。
畢竟官方提供了新的自定義方式椎镣,推薦大家用新方式來配置诈火,后續(xù)維護(hù)都會(huì)容易很多。