给github添加webhooks实现自动更新代码

目标是实现当代码push到github上时,服务器自动执行git pull 来更新代码
首先在项目文件夹初始化git

1
git init

设置git仓库地址(这里使用ssh方式,请确保你本地的ssh-key和github上的已设置对应好)

1
git remote add origin git@github.com:PEIC/peic.github.io.git

github的webhooks功能是当git仓库有变动的时候发出一个POST到指定地址,POST包含git的变动信息。
我们就是在服务端建立一个程序来响应这个POST,当变动类型为push时执行定义的shell脚本来更新代码。
作为前端我选择用nodejs来实现,nodejs已经有github-webhook-handler这个现成的模块来实现这个功能我们直接使用就行了。

程序代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var http = require('http')
var createHandler = require('github-webhook-handler')
//这里的secret必须与github里填写的一致。
var handler = createHandler({ path: '/', secret: 'myhashsecret' })


function run_cmd(cmd, args, callback) {
var spawn = require('child_process').spawn;
var child = spawn(cmd, args);
var resp = "";

child.stdout.on('data', function(buffer) { resp += buffer.toString(); });
child.stdout.on('end', function() { callback (resp) });
}


http.createServer(function (req, res) {
handler(req, res, function (err) {
res.statusCode = 404
res.end('no such location')
})
}).listen(7777)

handler.on('push', function (event) {
console.log('Received a push event for %s to %s',
event.payload.repository.name,
event.payload.ref);
run_cmd('sh', ['./deploy-dev.sh'], function(text){ console.log(text) });
})

被执行的更新脚本(COPY自:这里

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash

WEB_PATH='/data/website'//需要更新的项目路径
WEB_USER='root' //用户名

echo "Start deployment"
cd $WEB_PATH
echo "pulling source code..."
git reset --hard origin/master
git clean -f
git pull origin master
git checkout master
echo "changing permissions..."
chown -R $WEB_USER:$WEB_PATH root //用户名 用户所在组
echo "Finished."

服务端已经设置好了,这时我们开始在github上配置。

项目仓库->Setting->Webhooks&services->add webhook

Payload URL填写服务端项目运行的地址 可以直接填写ip加端口号也可以填写绑好的域名。这是=时需要注意如果地址为根路径的话需要在定义服务端代码的handler方法参数的path的值为’/‘,不是根路径的话填写对应的路径名。
Secret填写的为服务端handler方法参数里的secret。

点击Add webhook就完成了。

添加完成后webhook详情页面会有一个webhook执行POST的记录。

这里可以查看每次POST的时间和POST的内容。webhook添加成功后会自动执行一次POST操作。这时可以查看POST是否成功,失败会有一个感叹号icon在前面。可以展开查看服务端的Response来查找错误。

像这里的返回”no such location”就是因为handler方法path填写错误。

参考文章:尘埃落定->使用 GitHub / GitLab 的 Webhooks 进行网站自动化部署