gitee/github webhooks+nodejs实现自动拉取代码
需求
很简单,就是想在gitee上一提交代码,服务器就自动执行一个sh脚本。脚本的内容就是把代码拉取下来。gitee webhook和sh脚本都好办,关键是如何让服务器监听webhook发来的请求。
在网上一搜,各路大神各显神通,有用jenkins的,有用php的,还有travis CI…各位大佬,我就想实现一个简单的小功能,用这么牛逼的工具真没必要qwq(求饶
终于在谷歌上(百度真的搜不到)搜到一个用nodejs解决的,确实很方便。原博主写的很好,但是有几个小坑,我在这里提醒一下。
版权声明:CSDN博主「如风521」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_31667715/article/details/100117028
什么是webhook
webhook也叫钩子。粗浅的来说,就是你写一个小脚本,每次提交代码的时候,让gitee或者github帮你执行一下。重点是这个脚本是你自己编写的,但不是你自己执行的,是GitHub或者gitee帮你执行的。就像在钩子上放个东西,让人家帮你拉一下,所以叫钩子。
环境
- Git ,这个服务器上肯定要装的
- nodejs
配置公钥
配了公钥后,你打git clone (repo地址)
就不用输入密码了。这个很简单,网上教程很多。
有个小坑:配完公钥后git仓库地址一定要用ssh,而不是https
成功的结果就是你打git clone的时候不用输入密码了
用nodejs监听web-hooks服务
创建目录,用npm初始化,下载插件gitee-webhook-handler(ps:用了nodejs才发现它有很多好用的插件:
mkdir /usr/soft/web_hooks #创建目录
cd /usr/soft/web_hooks
npm init
npm install gitee-webhook-handler --save
创建js文件,按照自己的需求修改:
var http = require('http')
var createHandler = require('gitee-webhook-handler')
var handler = createHandler({ path: '/webhooks_push', secret: '654321'}) //post 所需要用到的密码,自己设置,跟下面对应就行
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) });
}
handler.on('error', function (err) {
console.error('Error:', err.message)
})
handler.on('Push Hook', function (event) {
console.log('Received a push event for %s to %s',
event.payload.repository.name,
event.payload.ref);
var name = event.payload.repository.name //这个name是仓库的名字
if (name === "Gitee FeedBack" || name === "xaiweb") {
run_cmd('sh', ['/www/xaiweb/pull.sh'], function (text) {// 需要执行的脚本位置
console.log(text)
});
}else {
console.log("unknow repository name:" + name);
}
})
try {
http.createServer(function (req, res) {
handler(req, res, function (err) {
res.statusCode = 404
res.end('no such location')
})
}).listen(6666) // 服务监听的端口,可以自行修改
}catch(err){
console.error('Error:', err.message)
}
原博主的这里的name没有定义,看日志才发现问题。
还有个小坑,如果你用gitee的话,push代码和点击“测试”的时候name的值是不一样的。前者是"Gitee FeedBack",后者是仓库名。(我的仓库名xaiweb
gitee和github应该也不一样,总之,测试的时候多看日志,就能发现问题。(日志下面有
启动服务
下载forever,这个能解决node服务自动停掉的问题。-g是全局安装
npm install -g forever
把nodejs目录下的forever软链接到系统的/usr/bin目录下,这样就能全局访问了
ln -s /usr/local/node(这里可能不一样)/lib/node_modules/forever/bin/forever /usr/bin/forever
不知道nodejs目录在哪的打whereis node或者which node试试,注意,这样找到的目录可能不是原始目录,而是软连接目录。
启动:
forever start -l ./forever.log -o ./out.log -e ./err.log webhook.js #第一次启动
forever start -a -l ./forever.log -o ./out.log -e ./err.log webhook.js #之后再启动打这个
这里给两个forever常用命令
forever list #列出服务,能看到日志在哪
forever stop + id或文件名 #停止服务
nginx反向代理
location ^~ /webhooks_push {
proxy_set_header Host $host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://127.0.0.1:6666;
}
如果你不会nginx也没啥问题,直接用ip:6666也行
gitee配置
密码就是跟上面那个对应的。
大功告成。
1月31日补充
如果用GitHub:
//webhook.js
var http = require('http')
var createHandler = require('github-webhook-handler')
var handler = createHandler({ path: '/', secret: '密码' })
// 上面的 secret 保持和 GitHub 后台设置的一致
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(6666)
handler.on('error', function (err) {
console.error('Error:', err.message)
})
handler.on('push', function (event) {
console.log('Received a push event form %s to %s',
event.payload.repository.name,
event.payload.ref);
run_cmd('sh', ['./pull.sh', event.payload.repository.name], function (text) { console.log(text) });
})
请求:http://ip:6666/
content type: application/json