服务器:centos7.4(阿里云)
使用宝塔控制面板,使用gitlab实现git项目(git服务器要大于4G。否则会卡)也可以使用码云,git等。
实现内容:分支,新建一个test分支。test提交,测试服更新。master更新,正式服更新。
实现原理:gitlab每次提交会给指定url发送一个post请求,其中会有相关提交信息。每次都提交测试服,测试服判断分支curl->post发送给正式服。
目录权限:正式服与测试服都给www权限,否则会提示无更新。使用的是宝塔,可以直接设定
如果是linux
- 要新建ssh并且给www权限
- 给wwwoot,www权限
- 新建/home/www,并且给www权限
- 生成账户所拥有keys
- 查看keys
- 将keys放到gitlab上。
- cd到目录并且更新。
- 然后测试git push提交,git pull更新如果不行,请用sudo -u www git pull
如果可以正常更新即可
sudo -u www mkdir /home/www/.ssh
sudo -u www chown -R www:www wwwroot
mkdir /home/www
chown -R www:www /home/www
sudo -u www ssh-keygen -t rsa -C "973873838@qq.com"
cat /home/www/.ssh/id_rsa.pub
cd /www/wwwroot/demo
git clone ......url
thinkphp 钩子实现源码
file_put_contents全部为写入文件,用于查看是否更新成功。
如果权限可用,那么下面的代码即可执行。
注意本身是禁用shell_exec的,要启用这个函数
<?php
namespace app\api\controller;
use think\Controller;
class Webhooks extends Controller
{
public function update()
{
if ($this->request->isPost()) {
var_dump($_POST);
file_put_contents(RUNTIME_PATH . 'master.log', json_encode(file_get_contents("php://input")));
}
if ($this->request->isGet()) {
exit('11111');
}
set_time_limit(0);
//这
file_put_contents(RUNTIME_PATH . 'webhooks.log', json_encode($_SERVER));
$token = empty($_SERVER['HTTP_X_GITLAB_TOKEN']) ? '' : $_SERVER['HTTP_X_GITLAB_TOKEN'];
if ($token !== 'testtokk') {
return '秘钥不正确';
}
$requestBody = file_get_contents("php://input");
$content = json_decode($requestBody, true);
if (empty($requestBody)) {
if (isset($_SERVER['HTTP_X_BUILD'])) {
file_put_contents(ROOT_PATH . 'runtime/zhengshi.log', $_SERVER);
return $this->build($content);
}
die('send fail');
}
$dev = 'test'; // 测试分支名
$root = ROOT_PATH;
$res = shell_exec("cd {$root} && git pull origin ".$dev." 2>&1");//以nginx用户运行
$res_log = '-------------------------'.PHP_EOL;
$res_log .= $content['user_name'] . ' 在' . date('Y-m-d H:i:s') . '向' . $content['repository']['name'] . '项目的' . $content['ref'] . '分支push了' . $content['total_commits_count'] . '个commit:' . PHP_EOL;
$res_log .= $res.PHP_EOL;
file_put_contents(RUNTIME_PATH . "git-webhook.log", $res_log, FILE_APPEND);//追加写入
if (empty($_SERVER['HTTP_X_BUILD']) && $content['ref'] !== 'refs/heads/' . $dev) {
$curl = curl_init();
//设置抓取的url
curl_setopt($curl, CURLOPT_URL, 'http://test.jjzbest.com/webhooks');
//设置头文件的信息作为数据流输出
curl_setopt($curl, CURLOPT_HEADER, 1);
//curl_setopt($curl, HTTP_CONTENT_TYPE, 'multipart/form-data');
//设置获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
//设置post方式提交
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
'X-GITLAB-TOKEN:'.$_SERVER['HTTP_X_GITLAB_TOKEN'],
'X-BUILD:true'
]);
//设置post数据
// curl_setopt($curl, CURLOPT_POSTFIELDS, [
// 'build'=>true
// ]);
//执行命令
$data = curl_exec($curl);
//关闭URL请求
curl_close($curl);
}
return 'SUCCESS';
}
/**
* 部署服务器运行的
*/
private function build($content)
{
$root = ROOT_PATH;
$res = shell_exec("cd {$root} && git pull -u origin master 2>&1");//以nginx用户运行
$res_log = '-------------------------'.PHP_EOL;
$res_log .= $content['user_name'] . ' 在' . date('Y-m-d H:i:s') . '向' . $content['repository']['name'] . '项目的' . $content['ref'] . '分支push了' . $content['total_commits_count'] . '个commit:' . PHP_EOL;
$res_log .= $res.PHP_EOL;
file_put_contents(RUNTIME_PATH . "git-webhook.log", $res_log, FILE_APPEND);//追加写入
}
public function aa()
{
$root = ROOT_PATH;
$res = shell_exec("cd {$root} && git pull 2>&1");
halt($res);
}
}