咱們一般須要在 PUSH 代碼到遠程倉庫時,線上環境會自動進行代碼同步,這時候就須要用到WebHook,它會自動回調咱們設定的http地址。php
經過請求咱們自已編寫的腳本,來拉取代碼,實現與遠程倉庫代碼的同步。git
1、咱們先建立一個本地倉庫web
echo "# 測試" > README.md git init git add README.md git commit -m "test"
在碼雲或 GitHub 上建立一個空倉庫,好比:test,而後讓本地倉庫與遠程倉庫關聯。shell
git remote add origin https://gitee.com/xxx/test.git git push -u origin master
2、在本地倉庫,添加WebHook文件,並提交到版本庫json
碼雲版:服務器
<?php $data = json_decode(file_get_contents('php://input'), true); // 碼雲WebHooks中配置的密碼 $password = "123456"; // 你本地的項目路徑 $path = "/data/wwwroot/test"; // 判斷密碼 if ($data['password'] === $password) { echo shell_exec("id -a"); echo shell_exec("cd {$path} && /usr/bin/git reset --hard origin/master && /usr/bin/git clean -f && /usr/bin/git pull 2>&1"); exit(); } http_response_code(404);
GitHub版:ssh
<?php // GitHub項目 Settings/Webhooks 中的 Secret $secret = "123456"; // 你本地的項目路徑 $path = "/data/wwwroot/test"; // 驗籤 $signature = $_SERVER['HTTP_X_HUB_SIGNATURE']; if ($signature) { $hash = "sha1=" . hash_hmac('sha1', file_get_contents("php://input"), $secret); if (strcmp($signature, $hash) == 0) { echo shell_exec("id -a"); echo shell_exec("cd {$path} && /usr/bin/git reset --hard origin/master && /usr/bin/git clean -f && /usr/bin/git pull 2>&1"); exit(); } } http_response_code(404);
3、登錄線上服務器,爲用戶生成 SSH 祕鑰,並配置碼雲或GitHub的項目公鑰。測試
配置公鑰主要的做用是免去每次 git 操做時須要輸入密碼。code
注意,這裏,咱們要爲 www 用戶或 nobody 用戶生成 ssh 祕鑰,別搞錯了。webhook 調用時,是 php 腳本當前執行的用戶。blog
具體是哪一個用戶能夠經過 echo shell_exec('id -a'); 來查看。
sudo mkdir -p /home/www/.ssh sudo chown -R www.www /home/www/.ssh sudo -Hu www ssh-keygen -t rsa
一路回車,直到結束,系統會在用戶的家目錄,生成 id_rsa 和 id_rsa.pub 兩個文件,即 id_rsa 密鑰 和 id_rsa.pub 公鑰。
cat /home/www/.ssh/id_rsa.pub
而後在 碼雲 項目管理 -> 公鑰管理 -> 添加公鑰 ,把 id_rsa.pub 中的內容添加。
在GitHub 帳號 -> Setting -> SSH and GPG keys ,把 id_rsa.pub 中的內容添加。
而後分別在碼雲和 GitHub 項目配置WebHook,注意地址必須能外網訪問的。
4、登錄線上服務器,並使用 ssh 協議 clone 項目
注意,咱們配置了項目的 ssh 公鑰,拉取項目要走 ssh 協議,而不是 https。
sudo -u www git clone git@gitee.com:xxx/test.git
注意,若是報錯, fatal: 不能建立工做區目錄 'test': 權限不夠 ,則須要建立一個同名 test 目錄,並把目錄所屬用戶修改爲 www。
chown -R www.www test
修改權限,注意你PHP運行時的用戶是誰,通常爲www,也有多是 nobody
sudo chown -R www . sudo chmod -R g+s . sudo -u www git pull
在本地提交文件,就能夠看到代碼自動同步到線上服務器了。
5、基於不一樣分支,來同步不一樣目錄下的代碼
這裏以gitee爲例:
<?php $data = json_decode(file_get_contents('php://input'), true); // 碼雲WebHooks中配置的密碼 $password = "123456"; // 你本地的項目路徑 $paths = [ 'master' => '/data/www/wwwroot/master', 'test' => '/data/www/wwwroot/test', 'develop' => '/data/www/wwwroot/develop', ]; // 獲取分支名 $ref = explode('/', $data['ref']); $branch = end($ref); // 判斷密碼 if ($data['password'] === $password && $data['total_commits_count'] > 0 && $paths[$branch] ) { $path = $paths[$branch]; echo shell_exec("id -a"); echo shell_exec("cd {$path} && /usr/bin/git checkout {$branch} 2>&1"); echo shell_exec("cd {$path} && /usr/bin/git reset --hard origin/{$branch} && /usr/bin/git clean -f && /usr/bin/git pull origin {$branch} 2>&1"); exit(); } http_response_code(404);
咱們在本地建立三個目錄,分別對應三個分支,其中一個分支代碼更新時,則自動同步。
注意,本地經過 sudo -u www git clone xxx 拉取代碼後,切換分支時,也須要指定用戶,否則會有權限問題。
sudo -u www git checkout develop