前言:
代码托管平台如:Github等提供了一个 Webhooks功能,每次 push 完代码,可以利用它实现代码的自动拉取,这样可以减少好多部署代码的麻烦事。
Webhooks
Webhooks 是代码托管平台提供的一个功能,对于任意一个项目,可以设置一个 URL,同时选择一些事件,当触发了这些事件(push、pull request、fork 等)时,代码托管平台会自动请求该 URL,并带上一些必要的参数。
实现(以GitHub为例)
设置回调URL 选择事件
登录GitHub,新建一个版本库,命名为 testWebhooks,依次点击 Settings -> Webhooks -> Add webhook
添加 Deploy keys
两个公钥
生成公钥
在服务器上执行下面命令
sudo mkdir /var/www/.ssh
//将目录 .ssh 的拥有者、所属组修改为 www-data
sudo chown -R www-data:www-data /var/www/.ssh
// 在 /var/www/.ssh 目录下生成密钥,同时将该密钥的拥有者、所属组修改为 www-data。在 Ubuntu 中,PHP 运行时的用户为 www-data,如果不修改,PHP 运行时的用户是读不到这个部署公钥的,也就拉不了代码了
sudo -Hu www-data ssh-keygen -t rsa -C "your_name@example.com"
如果不确定系统的 PHP 运行时使用的哪个用户,在测试机上建一个测试PHP文件test.php,然后执行以下即可
// test.php
<?php
system("whoami");
?>
查看并添加部署公钥
查看部署公钥
sudo cat /var/www/.ssh/id_rsa.pub
添加部署公钥
依次点击项目的 Setting -> Deploy keys -> Add deploy key,将公钥粘进去,点击 Add key 添加完成
准备钩子文件
之前设置的回调URL可以访问到的index.php的文件,如下:
<?php
// 切换到项目目录,执行 git pull,加上 2>&1 会输出一些错误信息,便于调试
shell_exec("cd /www/testWebhooks && git pull 2>&1");
?>
克隆项目文件
cd /www/
sudo -Hu www-data git clone git地址
到此为止,每次往项目中推送代码,测试服务器都会自动拉取代码到测试服务器上,如果没拉取成功,很有可能就是由于前面所说的部署秘钥及项目文件夹没有设置成拉取脚本(index.php文件)运行时的用户。
效果
打开项目,点击 Setting -> Webhooks,可以看到刚刚设置的回调 URL,点进去拉到最下面 Recent Deliveries,可是看到所有的被触发事件的请求
Request
Response
每一种事件发送的 Payload 格式是不一样的,关于 Payload 更多信息,请看官方文档: Event Types & Payloads
服务器拉取代码时进行验证,防止恶意攻击(设置的回调URL有可能被泄露,被认为请求)
添加 Webhooks 的时候,Secret 列填上一个随机字符串比如: testWebhooks
钩子函数文件 index.php 改为:
<?php
$secret = "testWebhooks"; //密钥,和 GitHub 上对应
$path = "/var/www/html/Webhooks"; //服务器上的项目文件目录
$signature = $_SERVER["HTTP_X_HUB_SIGNATURE"]; //获取散列字符串
if($signature) {
$rawPost = file_get_contents("php://input"); //获取收到的数据
list($algo, $hash) = explode("=", $signature, 2); //获取散列算法、散列值
if ($hash === hash_hmac($algo, $rawPost, $secret)) { //验证
shell_exec("cd /var/www/html/Webhooks && git pull 2>&1");
echo "代码拉取成功";
} else {
echo "Secret 验证失败";
}
} else {
echo "请输入 Secret";
}
注意:
每次触发事件,GitHub 会使用 SHA-1 将发送的数据和 Secret 一起散列,生成一个散列字符串,在钩子文件中需要对这个散列字符串进行验证。
对于其它代码托管平台,有的不提供 Secret 字段,有的 Secret 在钩子文件中直接验证,具体使用还需要研究一下官方说明
注:
原文:https://www.cnblogs.com/zhuchenglin/p/12757602.html