Git教程
当进行开发的环境在本地,而运行的环境要在服务端时,每一次提交代码都需要在服务端pull一次。而利用git的hooks功能,能够让我们省去这一步,下面我就以码云的webhooks为例,实现服务端的代码自动同步部署。
了解 git 的 hooks
关于 git 钩子
Git 能在特定的重要动作发生时触发自定义脚本。 有两组这样的钩子:客户端的和服务器端的。 客户端钩子由诸如提交和合并这样的操作所调用,而服务器端钩子作用于诸如接收被推送的提交这样的联网操作。 你可以随心所欲地运用这些钩子。
如何使用钩子
钩子都被存储在 Git 目录下的 ==hooks== 子目录中。 也即绝大部分项目中的 ==.git/hooks== 。 当你用 ==git init== 初始化一个新版本库时,Git 默认会在这个目录中放置一些示例脚本。这些脚本除了本身可以被调用外,它们还透露了被触发时所传入的参数。 所有的示例都是 shell 脚本,其中一些还混杂了 Perl 代码,不过,任何正确命名的可执行脚本都可以正常使用 —— 你可以用 Ruby 或 Python,或其它语言编写它们。 这些示例的名字都是以 ==.sample== 结尾,如果你想启用它们,得先移除这个后缀。
把一个正确命名且可执行的文件放入 Git 目录下的 hooks 子目录中,即可激活该钩子脚本。 这样一来,它就能被 Git 调用。 接下来,我们会讲解常用的钩子脚本类型。
具体使用可以参考官方文档:Git Hookes
了解 webhooks
钩子功能(callback),是帮助用户 push 了代码后,自动回调一个你设定的 http 地址。 这是一个通用的解决方案,用户可以自己根据不同的需求,来编写自己的脚本程序(比如发邮件,自动部署等);目前,webhooks 支持多种触发方式,支持复选。
webhooks 的请求方式为POST请求,有两种数据格式可以选择,JSON 和 web 的 form参数,可以自行选择是否使用密码来确定请求。(注意:该密码是明文)
不同托管平台的POST数据格式都不太一样,不过也不会有太大影响,只是解析数据的时候注意就行了,下面是码云的 Push 操作回调的 json 数据:
{ "before": "fb32ef5812dc132ece716a05c50c7531c6dc1b4d", "after": "ac63b9ba95191a1bf79d60bc262851a66c12cda1", "ref": "refs/heads/master", "user_id": 13, "user_name": "123", "user": { "name": "123", "username": "test123", "url": "https://gitee.com/oschina" }, "repository": { "name": "webhook", "url": "http://git.oschina.net/oschina/webhook", "description": "", "homepage": "https://gitee.com/oschina/webhook" }, "commits": [ { "id": "ac63b9ba95191a1bf79d60bc262851a66c12cda1", "message": "1234 bug fix", "timestamp": "2016-12-09T17:28:02 08:00", "url": "https://gitee.com/oschina/webhook/commit/ac63b9ba95191a1bf79d60bc262851a66c12cda1", "author": { "name": "123", "email": "123@123.com", "time": "2016-12-09T17:28:02 08:00" } } ], "total_commits_count": 1, "commits_more_than_ten": false, "project": { "name": "webhook", "path": "webhook", "url": "https://gitee.com/oschina/webhook", "git_ssh_url": "git@gitee.com:oschina/webhook.git", "git_http_url": "https://gitee.com/oschina/webhook.git", "git_svn_url": "svn://gitee.com/oschina/webhook", "namespace": "oschina", "name_with_namespace": "oschina/webhook", "path_with_namespace": "oschina/webhook", "default_branch": "master" }, "hook_name": "push_hooks", "password": "pwd" }
在 Linux + Apache + 码云的尝试
准备工作
1、首先你要搭建好LAMP的的开发环境
2、当然要有git的环境了
3、要将代码方在一个提供webhooks支持的代码托管平台上,如果自己搭建 git 服务器则要自己实现 webhooks 回调
开始干活
1、创建仓库
首先,我们创建一个仓库,获取相关的信息,先设置一下GIT全局,在执行第二步:生成公钥
设置GIT全局
git config --global user.name "红色螃蟹" git config --global user.email "2323946929@qq.com"
2、生成公钥
公钥有两个:1. git用户公钥(用于git clone时认证权限),2. 部署公钥
//linux命令 cd ~ rm -rf .ssh ssh-keygen -t rsa -C "2323946929@qq.com" //然后就是设置密码了,不设置就一直回车 //上面的命令分别是 1.进入用户目录。2.删除.ssh目录。3.创建公钥 //接着继续 cat .ssh/id_rsa.pub //会输出你的公钥,复制到coding绑定公钥即可,然后就可以去测试你的了
3、配置公钥
将公钥的内容粘贴到用户->设置 中的SSH公钥中
4、项目部署
绑定好之后,到要自动部署的目录
git init git remote add 别名 项目地址 git pull 别名 分支//第一次连接会要你输入yes
其实这些代码就是,第1步中的命令行代码
5、添加Hook文件(钩子文件)
在你的项目根目录建立一个目录hook, 里面放上一个php文件githook.php,内容如下:
<?php //var_dump(get_current_user()); //仓库地址 //$remote = 'https://gitee.com/qdxcy/test.git'; //GitLab 服务器上项目目录 $www_file = '/home/wwwroot/ht-admin/'; //打开网站目录下的hooks.log文件 需要在服务器上创建 并给写权限 $fs = fopen($www_file . 'hooks.log', 'a'); //脚本执行用户 $who = exec('whoami'); fwrite($fs, $who . '================ Update Start ===============' . PHP_EOL . PHP_EOL); //自定义字串掩码 用于验证 $access_token = 'e1bfd762321e409cee4ac0b6e849876c'; //接受的ip数组,也就是允许哪些IP访问这个文件 这里是 GitLab 服务器IP $access_ip = array('8.8.8.8'); //获取请求端的 IP 和 token $client_token = $_GET['token']; $client_ip = $_SERVER['REMOTE_ADDR']; //把请求的 IP 和时间写进 log fwrite($fs, 'Request on [' . date("Y-m-d H:i:s") . '] from [' . $client_ip . ']' . PHP_EOL); //验证 Token 有错就写进日志并退出 if ($client_token !== $access_token) { echo "error 403"; fwrite($fs, "Invalid token [{$client_token}]" . PHP_EOL); exit(0); } //验证 IP if (!in_array($client_ip, $access_ip)) { echo "error 503"; fwrite($fs, "Invalid ip [{$client_ip}]" . PHP_EOL); exit(0); } //获取请求端发送来的信息,具体格式参见 GitLab 的文档 $json = file_get_contents('php://input'); $data = json_decode($json, true); //如果有需要 可以打开下面,把传送过来的信息写进log fwrite($fs, 'Data: ' . print_r($data, true) . PHP_EOL); //执行shell命令并把返回信息写进日志 $output = shell_exec("cd $www_file && git pull origin master 2>&1"); fwrite($fs, 'Info:' . $output . PHP_EOL); fwrite($fs, PHP_EOL . '================ Update End ===============' . PHP_EOL . PHP_EOL); $fs and fclose($fs); var_dump($output);
确保你的hook文件可以访问:http://www.xxxx.com/hook/githook.php ,钩子准备完成。
6、配置webhooks
如果链接可用,则大功告成,只需把仓库 clone 之后,再向码云提交,变回自动被 服务器 pull
注意事项
如果配置都没有问题,但是就是不会自动拉取,那应该是用户的权限配置问题,可以先查看运行php代码的具体用户是什么,然后为该用户开启权限。
system("whoami"); // 查看是哪个用户执行该命令
可能用到的命令行
//切换用户,切换到www用户 su www //针对文件变更用户权限 chown www:www githook.php //或 chown www:www hook/githook.php -R