思路
你在本地跑一个项目,当你push到远程仓库(github)的时候,远程仓库会及时更新。这时触发webhock钩子。webhock钩子需要绑定你的服务接口,并监听你的 git 事件。比如本文案例push
事件,监听到后,就触发你写好的脚本文件。(cd dir, npm install, pm2 start … 等等 )
,
项目准备
前提你要有github项目,这里就不多说了
打开项目位置 settings
payload url 远程可以访问的,可以http, 路径只写到端口也没事,但要跟你代码匹配好 secret: 你自定义字符串,验证作用
代码
核心包 node-webhock-handler
//还要个类似的github-webhock-handler
npm -y init
koa-api.js
const http = require('http')
const spawn = require('child_process').spawn
const createHandler = require('github-webhook-handler')
const handler = createHandler({
path: '/push', // path 如果没有 / 但如果配置多了,建议还是加个path
secret: 'xxxxxxxxxx' // webhoack 配置
})
http.createServer((req, res) => {
handler(req, res, function(err) {
res.statusCode = 404
res.end('no such location')
})
}).listen(8001)
handler.on('error', err => {
console.error('Error:', err.message)
})
handler.on('push', e => { // 监听的push 事件
try {
const s = spawn('sh', ['./auto_build.sh'], {
cwd: `../${e.payload.repository.name}`
})
s.stdout.on('data', (data) => {
console.log(`${e.payload.repository.name}: ${data}`);
})
s.stderr.on('data', (data) => {
console.log(`${e.payload.repository.name}: ${data}`);
});
console.log(e.payload.repository.name, 'has rebuild');
} catch (e) {
console.log(e)
}
})
auto_build.sh
ls // 我暂时只用了 ls 做 测试
package.json
{
"name": "koa-api",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "nodemon koa-api.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"child_process": "^1.0.2",
"crypto": "^1.0.1",
"github-webhook-handler": "^1.0.0"
},
"devDependencies": {
"nodemon": "^2.0.4"
}
}
部署服务器
如果没有,就用花生壳做测试,毕竟需要外网条件。http 要money, 毕竟现在什么都要钱。哎
我做调试,还是用的nodemon
部署上去后 自己git push 自己的项目
下面几个文件名 就是 ls
打印的,
现在再看github
打钩就说明传递成功,跟你服务器接口绑定成功,如果有问题就是你代码有问题了。
自动化方案 脚本
先在服务器找一个位置
git clone xxx.git
pm2 start xx.js --name koa-api
可以运行起来
修改刚刚的脚本
auth_build.sh
cd /xxxx // 绝对路径 此时路径已打开文件夹
pm2 stop koa-api // 先暂停pm2 服务
git pull // 最好强制 git fetch --all git reset --hard origin/master
npm install // 防止多到依赖,安装
pm2 restart koa-api // 重启
有更好的方案 望告知
最后附上大佬写的 多个webhock配置
const http = require('http')
const createHandler = require('node-github-webhook')
const handler = createHandler([ // 多个仓库
{
path: '/app1',
secret: 'CUSTOM'
},
{
path: '/app2',
secret: 'CUSTOM'
}
])
// var handler = createHandler({ path: '/webhook1', secret: 'secret1' }) // 单个仓库
http.createServer(function (req, res) {
handler(req, res, function (err) {
res.statusCode = 404
res.end('no such location')
})
}).listen(7777)
handler.on('error', function (err) {
console.error('Error:', err.message)
})
handler.on('push', function (event) {
console.log(
'Received a push event for %s to %s',
event.payload.repository.name,
event.payload.ref
)
switch (event.path) {
case '/app1':
runCmd('sh', ['./app1_deploy.sh', event.payload.repository.name], function (text) { console.log(text) })
break
case '/app2':
runCmd('sh', ['./app2_deploy.sh', event.payload.repository.name], function (text) { console.log(text) })
break
default:
// 处理其他
break
}
})
function runCmd (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)
})
}
完工,吃饭