一漠趁、Webhook 介紹與作用簡(jiǎn)介
Webhook亡容,顧名思義就是鉤子叭莫,簡(jiǎn)而言之,可以在特定情況下觸發(fā)特定的操作经宏。例如在遠(yuǎn)程git倉(cāng)庫(kù)中進(jìn)行了push犀暑、tag等操作時(shí),自動(dòng)在遠(yuǎn)程server端自動(dòng)拉取烁兰、編譯代碼耐亏。
以下是一個(gè)push代碼到遠(yuǎn)程倉(cāng)庫(kù)后,自動(dòng)拉取代碼進(jìn)行編譯后沪斟,將生成的Webassembly相關(guān)的文件(.js广辰,.wasm)和版本號(hào)push到遠(yuǎn)程倉(cāng)庫(kù)中的demo。
二主之、demo實(shí)現(xiàn)
1. 倉(cāng)庫(kù)設(shè)置(以gitee為例)
首先择吊,需要擁有項(xiàng)目的管理者權(quán)限,點(diǎn)擊項(xiàng)目首頁(yè)上方的管理槽奕,然后點(diǎn)擊左側(cè)菜單下方的WebHooks几睛,進(jìn)入到以下截圖的設(shè)置頁(yè)面。
在上面的的界面中粤攒,我已經(jīng)添加了一個(gè)Webhook所森,觸發(fā)類型為push,同時(shí)還有一個(gè)密碼琼讽。
當(dāng)你push代碼到遠(yuǎn)程倉(cāng)庫(kù)時(shí),會(huì)往這里設(shè)置的URL發(fā)送一個(gè)攜帶著設(shè)置好密碼的POST請(qǐng)求洪唐。當(dāng)然你也可以勾選其他的操作類型钻蹬。
2. PHP代碼實(shí)現(xiàn)
- hooks.php
<?php
// 本地倉(cāng)庫(kù)路徑
$local = '/data/wwwroot/default/hooks/laserbox';
// 安全驗(yàn)證字符串,為空則不驗(yàn)證
$token = '123456';
// payload為字符串凭需,需要經(jīng)過解析
$payload = file_get_contents('php://input');
if (!$payload) {
header('HTTP/1.1 400 Bad Request');
die('HTTP HEADER or POST is missing.');
}
$content = json_decode($payload, true);
// 如果啟用驗(yàn)證问欠,并且驗(yàn)證失敗,返回錯(cuò)誤
if ($token && $content['password'] != $token) {
header('HTTP/1.1 403 Permission Denied');
die('Permission denied.');
}
//最后會(huì)執(zhí)行一個(gè)腳本編譯代碼粒蜈,然后再push代碼到遠(yuǎn)程
//所以會(huì)重復(fù)觸發(fā)WebHooks顺献,因此此處判斷是否是本地的推送
if($content['commits'][0]['author']['name'] == 'handsomeTaoTao'){
header('HTTP/1.1 403 Permission Denied');
die('self push.');
}
/*
* 這里有幾點(diǎn)需要注意:
*
* 1.確保PHP正常執(zhí)行系統(tǒng)命令。寫一個(gè)PHP文件枯怖,內(nèi)容:
* `<?php echo shell_exec('ls -la')`
* 在通過瀏覽器訪問這個(gè)文件注整,能夠輸出目錄結(jié)構(gòu)說明PHP可以運(yùn)行系統(tǒng)命令。
*
* 2、PHP一般使用www-data或者nginx用戶運(yùn)行肿轨,PHP通過腳本執(zhí)行系統(tǒng)命令也是用這個(gè)用戶寿冕,
* 在通過瀏覽器訪問這個(gè)文件,能夠輸出目錄結(jié)構(gòu)說明PHP可以運(yùn)行系統(tǒng)命令椒袍。
*
* 2驼唱、PHP一般使用www-data或者nginx用戶運(yùn)行,PHP通過腳本執(zhí)行系統(tǒng)命令也是用這個(gè)用戶驹暑,
* 所以必須確保在該用戶家目錄(一般是/home/www-data或/home/nginx)下有.ssh目錄和
* 一些授權(quán)文件玫恳,以及git配置文件,如下:
* ```
* + .ssh
* - authorized_keys
* - config
* - id_rsa
* - id_rsa.pub
* - known_hosts
* - .gitconfig
* ```
*
* 3.在執(zhí)行的命令后面加上2>&1可以輸出詳細(xì)信息优俘,確定錯(cuò)誤位置
*
* 4.git目錄權(quán)限問題京办。比如:
* `fatal: Unable to create '/data/www/html/awaimai/.git/index.lock': Permission denied`
* 那就是PHP用戶沒有寫權(quán)限,需要給目錄授予權(quán)限:
* ``
* sudo chown -R :www-data /data/www/html/awaimai`
* sudo chmod -R g+w /data/www/html/awaimai
* ```
*
* 5.SSH認(rèn)證問題兼吓。如果是通過SSH認(rèn)證臂港,有可能提示錯(cuò)誤:
* `Could not create directory '/.ssh'.`
* 或者
* `Host key verification failed.`
*
*/
// shell_exec函數(shù)默認(rèn)是禁止的,無(wú)法使用的話需要進(jìn)php.ini修改相關(guān)配置
//執(zhí)行shell時(shí)视搏,沒有sudo仿佛會(huì)執(zhí)行不成功审孽,只執(zhí)行一小段,加了sudo之后執(zhí)行成功浑娜,可以為運(yùn)行php的用戶添加sudo權(quán)限佑力,參考資料有相關(guān)問題
echo shell_exec("cd {$local} && sudo sh ./autoCompiled.sh");
die("done " . date('Y-m-d H:i:s', time()));
- autoCompiled.sh
#!/bin/sh
source /data/git/emsdk/emsdk_env.sh // 載入命令,否則在命令行中無(wú)法使用emcc等編譯用的命令
cd /data/git/Webassembly-Lib/Demo/ // 進(jìn)入到執(zhí)行命令的目錄中
git pull
rm -f src/version.h
git rev-list HEAD | sort > config.git-hash
LOCALVER=`wc -l config.git-hash | awk '{print $1}'`
if [ $LOCALVER \> 1 ] ; then
VER=`git rev-list origin/master | sort | join config.git-hash - | wc -l | awk '{print $1}'`
if [ $VER != $LOCALVER ] ; then
VER="$VER+$(($LOCALVER-$VER))"
fi
if git status | grep -q "modified:" ; then
VER="${VER}M"
fi
VER="$VER $(git rev-list HEAD -n 1 | cut -c 1-7)"
GIT_VERSION=r$VER
else
GIT_VERSION=
VER="x"
fi
rm -f config.git-hash
cat version.h.template | sed "s/\$FULL_VERSION/$GIT_VERSION/g" > src/version.h
# 編譯和提交代碼
make
git add .
git commit -m 'Auto Compiled By handsomeTaoTao'
git push
三筋遭、結(jié)束語(yǔ)
目前這個(gè)demo還只是實(shí)現(xiàn)了比較簡(jiǎn)單的功能打颤,可以進(jìn)一步優(yōu)化功能,例如在瀏覽器訪問該地址時(shí)顯示上一次編譯是否成功的信息漓滔,失敗的話則顯示錯(cuò)誤信息编饺,這樣子可以方便調(diào)試。
參考資料
stackoverflow: php-sudo-in-shell-exec
Gitee 配置文檔
Github响驴、GitLab透且、Gitee使用Webhooks實(shí)現(xiàn)代碼自動(dòng)部署