在 Coding 使用 Webhook 实现自动部署

最近碰到这样的一个需求,就是本地提交代码到 git 仓库以后需要网站远程自动同步代码。
因为项目不便公开,所以 Coding 的免费的私有仓库成了首选
看了下 Coding 的 webhook 正好能满足这个需求。既然如此,那我们先来看下 Webhook 的概念吧

WebHook

Webhook 允许第三方应用监听 Coding.net 上的特定事件,在这些事件发生时通过 HTTP POST 方式通知( 超时5秒) 到第三方应用指定的 Web URL。 例如项目有新的内容 Push,或是 Merge Request 有更新等。 WebHook 可方便用户实现自动部署,自动测试,自动打包,监控项目变化等。

Webhook 的每个 POST 请求都有包含特殊的 Header, 默认超时时间为 2s

1
2
Header  说明
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
19
const 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
地址是 服务器 Webhook 地址 比如我是 http://12x.xxx.xxx.xxx/webhook, Token 随便自己填一个,别被别人猜出来就行,填完点一下测试,会向你的服务器 post 一下,这时你的服务器就行自动 git pull 了!