Gitee Webhook 實現自動拉取代碼並編譯代碼

1、Webhook 介紹與做用簡介

Webhook,顧名思義就是鉤子,簡而言之,能夠在特定狀況下觸發特定的操做。例如在遠程git倉庫中進行了push、tag等操做時,自動在遠程server端自動拉取、編譯代碼。 如下是一個push代碼到遠程倉庫後,自動拉取代碼進行編譯後,將生成的Webassembly相關的文件(.js,.wasm)和版本號push到遠程倉庫中的demo。php

2、demo實現

1. 倉庫設置(以gitee爲例)

首先,須要擁有項目的管理者權限,點擊項目首頁上方的管理,而後點擊左側菜單下方的WebHooks,進入到如下截圖的設置頁面。 html

WebHooks設置界面
]

在上面的的界面中,我已經添加了一個Webhook,觸發類型爲push,同時還有一個密碼。 當你push代碼到遠程倉庫時,會往這裏設置的URL發送一個攜帶着設置好密碼的POST請求。固然你也能夠勾選其餘的操做類型。nginx

Webhook添加界面.png

2. PHP代碼實現

  • hooks.php
<?php

// 本地倉庫路徑
$local = '/data/wwwroot/default/hooks/laserbox';

// 安全驗證字符串,爲空則不驗證
$token = '123456';

//  payload爲字符串,須要通過解析
$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);

// 若是啓用驗證,而且驗證失敗,返回錯誤
if ($token && $content['password'] != $token) {
    header('HTTP/1.1 403 Permission Denied');
    die('Permission denied.');
}

//最後會執行一個腳本編譯代碼,而後再push代碼到遠程
//因此會重複觸發WebHooks,所以此處判斷是不是本地的推送
if($content['commits'][0]['author']['name'] == 'handsomeTaoTao'){
        header('HTTP/1.1 403 Permission Denied');
        die('self push.');
}

/*
 * 這裏有幾點須要注意:
 *
 * 1.確保PHP正常執行系統命令。寫一個PHP文件,內容:
 * `<?php echo shell_exec('ls -la')`
 * 在經過瀏覽器訪問這個文件,可以輸出目錄結構說明PHP能夠運行系統命令。
 *
 * 二、PHP通常使用www-data或者nginx用戶運行,PHP經過腳本執行系統命令也是用這個用戶,
 * 在經過瀏覽器訪問這個文件,可以輸出目錄結構說明PHP能夠運行系統命令。
 *
 * 二、PHP通常使用www-data或者nginx用戶運行,PHP經過腳本執行系統命令也是用這個用戶,
 * 因此必須確保在該用戶家目錄(通常是/home/www-data或/home/nginx)下有.ssh目錄和
 * 一些受權文件,以及git配置文件,以下:
 * ```
 * + .ssh
 *   - authorized_keys
 *   - config
 *   - id_rsa
 *   - id_rsa.pub
 *   - known_hosts
 * - .gitconfig
 * ```
 *
 * 3.在執行的命令後面加上2>&1能夠輸出詳細信息,肯定錯誤位置
 *
 * 4.git目錄權限問題。好比:
 * `fatal: Unable to create '/data/www/html/awaimai/.git/index.lock': Permission denied`
 * 那就是PHP用戶沒有寫權限,須要給目錄授予權限:
 * ``
 * sudo chown -R :www-data /data/www/html/awaimai`
 * sudo chmod -R g+w /data/www/html/awaimai
 * ```
 *
 * 5.SSH認證問題。若是是經過SSH認證,有可能提示錯誤:
 * `Could not create directory '/.ssh'.`
 * 或者
 * `Host key verification failed.`
 *
 */

// shell_exec函數默認是禁止的,沒法使用的話須要進php.ini修改相關配置
//執行shell時,沒有sudo彷彿會執行不成功,只執行一小段,加了sudo以後執行成功,能夠爲運行php的用戶添加sudo權限,參考資料有相關問題
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  // 載入命令,不然在命令行中沒法使用emcc等編譯用的命令
cd  /data/git/Webassembly-Lib/Demo/  // 進入到執行命令的目錄中
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

複製代碼

3、結束語

目前這個demo還只是實現了比較簡單的功能,能夠進一步優化功能,例如在瀏覽器訪問該地址時顯示上一次編譯是否成功的信息,失敗的話則顯示錯誤信息,這樣子能夠方便調試。git


參考資料
stackoverflow: php-sudo-in-shell-exec
Gitee 配置文檔
Github、GitLab、Gitee使用Webhooks實現代碼自動部署 shell

相關文章
相關標籤/搜索