最近碰到这样的一个需求,就是本地提交代码到 git 仓库以后需要网站远程自动同步代码。
因为项目不便公开,所以 Coding 的免费的私有仓库成了首选
看了下 Coding 的 webhook 正好能满足这个需求。既然如此,那我们先来看下 Webhook 的概念吧
Webhook 允许第三方应用监听 Coding.net 上的特定事件,在这些事件发生时通过 HTTP POST 方式通知( 超时5秒) 到第三方应用指定的 Web URL。 例如项目有新的内容 Push,或是 Merge Request 有更新等。 WebHook 可方便用户实现自动部署,自动测试,自动打包,监控项目变化等。
Webhook 的每个 POST 请求都有包含特殊的 Header, 默认超时时间为 2s1
2Header 说明
X-Coding-Event 事件名(例如: push, Merge Request, Task)
大致原理就是 push 代码到 Coding 后,Coding 向我的服务器 post ,然后我的服务器接收到后就会执行响应的操作。每个 POST 请求都有包含特殊的 Header 里面有事件名,可以依据这个来判断是什么事件,另外为了防止伪造, post 里还包含了 Token
好了,接下来进行实际演示吧。
既然是私有项目,要想 git pull 下来,肯定要配置 ssh key 了
但是服务器上的 ssh 又不想让它有完全的权限,毕竟你总不可能在服务器上改代码然后 push 到 Coding 上吧。
好在 Coding 提供了项目部署公钥设置,对项目只拥有读权限,这样相对来说比较安全
看上图,新建一个部署公钥,填入你服务器上的 ssh-rsa 公钥后就是上面的样子了
在你的项目里加入 webhook 的操作,比如 Nodejs 的 Express 项目是加入类似下面代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19const exec = require('child_process').exec;
router.post('/webhook', (req, res) => {
if ('hooks' === req.body['token']) {
exec('git pull', {'cwd': '/home/kieran/projects/app'},
(error, stdout, stderr) => {
console.log('stdout========================\n' + stdout);
console.log('stderr========================\n' + stderr);
if (error !== null) {
res.send('<pre>fail!!!\n' + stdout + error + '</pre>');
} else {
res.send('<pre>done!!!\n' + stdout + '</pre>');
}
});
} else {
console.log(' failed token ');
res.send('<pre>token不正确?</pre>');
}
});
这里有一点要注意一下,child_process 模块的 exec 命令执行时的第二个参数中,cwd 表示命令执行的目录,一开始我写的是’~/projects/app’, 然后死活没反应,折腾了 N 久,感觉不会再爱了。谨记,这里的 cwd 只能用绝对路径,不能用家路径的简写。
好了,服务器操作写完了,只要再在 Coding 上填一下服务器地址和 Token 就行了
地址是 服务器 Webhook 地址 比如我是 http://12x.xxx.xxx.xxx/webhook, Token 随便自己填一个,别被别人猜出来就行,填完点一下测试,会向你的服务器 post 一下,这时你的服务器就行自动 git pull 了!