類型
coding 鉤子
github 鉤子
環境
服務端:阿里云虛擬主機(Ubuntu16.04)
coding 自動部署 WebHook3.0
windows 10 開發環境
部署
服務器虛擬主機配置
coding 代碼托管配置
本地代碼提交
服務端配置
1、創建web服務器用戶目錄
這里以www用戶為例,不同的環境請根據自己環境自行修改
sudo mkdir /var/www/.ssh sudo chown -R www:www /var/www/.ssh/
2、生成公鑰(兩個)
git用戶公鑰(個人公鑰通用)
部署公鑰(部署公鑰用以部署項目, 只針對項目)
其實配置一個個人公鑰就可以,也就是通用公鑰了
3、用戶公鑰
用于git clone時認證權限
ssh-keygen -t rsa -C "Tinywan@gmail.com" # 然后一直回車就行 # 生成的文件通常是 /root/.ssh/id_rsa,如果非root用戶請查看提示上的路徑
4、部署公鑰(非必需)
sudo -Hu www ssh-keygen -t rsa # 請選擇 "no passphrase",一直回車下去 #sudo cat /var/www/.ssh/id_rsa.pub # 這個只是針對單個項目的 sudo cat /home/www/.ssh/id_rsa.pub # 查看生成的密鑰內容,復制全部
-Hu www 命令: -u 代表切換到哪一個用戶,這里說的是www -H 代表切換HOME環境變量的值,也就是password文件中www用戶對應的home目錄
5、準備鉤子文件
在你的站點目錄建立一個目錄hook,我這里站點目錄為:/home/www/web/,所有hook文件路徑為:/home/www/web/hook,在hook目錄新建index.php文件
參考demo
<?php error_reporting(1); // 生產環境web目錄 $web_path = '/home/www/web/hook/auto-test'; $user = 'www'; $group = 'www'; //作為接口傳輸的時候認證的密鑰 $valid_token = '1954FD0D6'; //調用接口被允許的ip地址 $valid_ip = array('192.168.14.2','192.168.14.1','192.168.14.128'); $client_ip = $_SERVER['REMOTE_ADDR']; $fs = fopen('./auto_hook.log', 'a'); fwrite($fs, 'Request on ['.date("Y-m-d H:i:s").'] from ['.$client_ip.']'.PHP_EOL); $json_content = file_get_contents('php://input'); $data = json_decode($json_content, true); fwrite($fs, 'Data: '.json_encode($data).PHP_EOL); fwrite($fs, '======================================================================='.PHP_EOL); $fs and fclose($fs); if (empty($data['token']) || $data['token'] !== $valid_token) { exit('aInvalid token request'); } $repo = $data['repository']['name']; $cmd = "cd $web_path && git pull"; shell_exec($cmd);
在hook目錄下建立一個自己coding 項目名(只是為了統一,你可以新建一個其他的):auto-test
最后的目錄結構為:
├── hook │ ├── auto-test │ │ │ └── index.php
6、修改目錄權限
chmod -R u+x /home/www/web/hook
7、域名解析
解析一個域名到linux系統,使用Nginx做一個代理,nginx虛擬主機配置信息如下:
server { server_name auto.tinywan.com; set $root_path /home/www/web/hook; root $root_path; location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php?s=/$1 last; } } location ~ .php$ { fastcgi_pass unix:/var/run/php7.1.9-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; fastcgi_buffer_size 128k; fastcgi_buffers 4 256k; fastcgi_busy_buffers_size 256k; fastcgi_connect_timeout 10000; fastcgi_send_timeout 6000; fastcgi_read_timeout 6000; } }
以上域名 auto.tinywan.com已經被A記錄到Linux外網IP了,阿里云域名解析
8、驗證的hook鉤子目錄的index.php文件可以訪問
訪問:http://auto.tinywan.com/index.php 輸出:error request // 表示可以正常訪問
9、配置git
git config --global user.name "Tinywan" git config --global user.email "Tinywan@gmail.com" # 郵箱請與conding上一致
10、配置公鑰
復制:/home/www.ssh/id_rsa.pub內容到個人設置頁https://coding.net/user/account/setting/keys,【新增公鑰】添加即可
id_rsa.pub 文件內容
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABBBABAQChrujULy3U56wS5jLJ0rAJMtv2MNABhbqU1kaiiiyUGFz9+Ndwel8o4dW4whmFRWBodDppc2gpDcF/UM6v7DLzHYOd/38BDp0vRz+zhgZ0BCfyeUV958tpTI6uQyjFil3jwDrKvDqeS4eVnb1fJZfnk/utcFCkVSjhae1sBqM10bkaQmsmwLKr7fN6DeUox9nYkknDqaD645wYplW/qFAXItHOaaZzgTpbAuEb4uss0BCtiutsDFsJwcuXlAsvg4xwsTmagdlz+FhTksCnGALcB10kaz0EY2g9NOHVCqQ4QU4TyNmUVwBHYfj6LAGALO4NAHfwErzKgqfRhBLzDsKB www@Tinywan
11、配置 WebHook
選擇項目(auto-test) > 設置 > 【WebHook】 > 【新建 WebHook】 > 粘貼你的hook/index.php所在的網址:http://auto.tinywan.com/index.php, 令牌可選,但是建議寫上。
稍過幾秒刷新頁面查看hook狀態,顯示為綠色勾就OK了
12、服務端初始化項目
我們需要先在服務器上clone一次,以后都可以實現自動部署了
sudo -Hu www git clone https://git.coding.net/Tinywan/auto-test.git /home/www/web/hook/auto-test/ --depth=1
13、Windows客戶端
(1)開發端也克隆一份代碼
$ git clone https://git.coding.net/Tinywan/auto-test.git Cloning into 'auto-test'... remote: Counting objects: 3, done. remote: Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. Checking connectivity... done.
(2)新建文件index.php
<?php echo "Hell Coding";
(3)提交本地的代碼
$ git add ./ $ git commit -m "test hook" $ git push -u origin master
(4)查看服務端文件是否已經更新
├── auto-test └── index.php
發現目標目錄里就剛才提交的index.php文件了
立即訪問:http://auto.tinywan.com/auto-test/index.php
鉤子file_get_contents('php://input')接受的文件內容
{ "ref": "refs/heads/master", "before": "90d67c99a3077a7a6823c50a95275812471ecf47", "commits": [ { "committer": { "name": "Tinywan", "email": "756684177@qq.com" }, "web_url": "https://coding.net/u/Tinywan/p/auto-test/git/commit/3e55e1c6aa0d064ba4fede1556f0e2bb14c0bed3", "short_message": "json_encode($_SERVER)n", "sha": "3e55e1c6aa0d064ba4fede1556f0e2bb14c0bed3" } ], "after": "3e55e1c6aa0d064ba4fede1556f0e2bb14c0bed3", "event": "push", "repository": { "owner": { "path": "/u/Tinywan", "web_url": "https://coding.net/u/Tinywan", "global_key": "Tinywan", "name": "Tinywan", "avatar": "/static/fruit_avatar/Fruit-14.png" }, "https_url": "https://git.coding.net/Tinywan/auto-test.git", "web_url": "https://coding.net/u/Tinywan/p/auto-test", "project_id": "3351025", "ssh_url": "git@git.coding.net:Tinywan/auto-test.git", "name": "auto-test", "description": "auto-test" }, "user": { "path": "/u/Tinywan", "web_url": "https://coding.net/u/Tinywan", "global_key": "Tinywan", "name": "Tinywan", "avatar": "/static/fruit_avatar/Fruit-14.png" }, "token": "1954FD0D6" }
以下是完整的鉤子
完整的鉤子代碼(兼容GitHub和Coding)
<?php error_reporting(1); // 配置 $secret = '1989BC88338CB4DABEF20BD7C54FD0D6'; $userAgent = $_SERVER['HTTP_USER_AGENT']; $signature = 'sha1=e0ec9317f440f3fd47631852ef585c6b2680e8f8'; if (substr_count($userAgent, 'GitHub') >= 1) { $signature = $_SERVER['HTTP_X_HUB_SIGNATURE']; } elseif (substr_count($userAgent, 'Coding') >= 1) { $signature = $_SERVER['HTTP_X_CODING_SIGNATURE']; } list($hash_type, $hash_value) = explode('=', $signature, 2); $jsonContent = file_get_contents("php://input"); $checkHash = hash_hmac($hash_type, $jsonContent, $secret); // e0ec9317f440f3fd47631852ef585c6b2680e8f8 $fs = fopen('./auto_hook.log', 'a'); $data = json_decode($jsonContent, true); fwrite($fs, 'Request on [' . date("Y-m-d H:i:s") . '] from [' . $data['pusher']['name'] . ']' . PHP_EOL); fwrite($fs, 'Data: '.json_encode($data).PHP_EOL); fwrite($fs, 'Service '.json_encode($_SERVER).PHP_EOL); // sha1 驗證 if ($checkHash && $checkHash === $hash_value) { fwrite($fs, '認證成功,開始更新 ' . PHP_EOL); $repository = $data['repository']['name']; $pwd = getcwd(); $command = 'cd .. && cd ' . $repository . ' && git pull'; fwrite($fs, 'command '.$command.PHP_EOL); if (!empty($repository)) { shell_exec($command); fwrite($fs, $repository . ' 更新完成 ' . PHP_EOL); } $fs and fclose($fs); }