webhook实现github代码自动部署

3,132 阅读2分钟

如果提交到github的代码能自动部署到服务器上多好?

准备

从github拉代码

1、生成ssh key

ssh-keygen -t rsa
cat .ssh/id_rsa.pub

2、添加服务器ssh key:github.com/settings/ke… 3、clone代码仓库

部署

从github拉下代码后,需要做些事更新代码,不同类型的项目可能是完全不一样的。 比如一个webpack项目,可能需要:

  • npm install
  • 构建
  • build产出打包、迁移到server静态资源目录

又比如一个node service,可能需要:

  • npm install
  • 重启应用

自动部署

目的

“要把大象装冰箱,拢共分三步”

要把代码自动部署到服务器,也需要三步: 1、本地 -> github:push 2、github -> server:通知、pull 3、server:构建或重启

image

这里的关键在2,github到server的通知。

通知-github端:webhook

webhook是github提供的能力,即在仓库发生改变时,向某一server发起请求。 在仓库的setting里,有增加webhook的入口:

image

配置页面这样:

image

其中URL即接受通知的server;type选json不然后面会报错;secret可选。

配置好后,如果本地push了代码,github就会向接口发一次请求。此时请求是失败的:

image

通知-server端

接下来我们需要用node开发一个监听配置端口的app,代码很简单:

const http = require('http')
const spawn = require('child_process').spawn
const createHandler = require('github-webhook-handler')
const handler = createHandler({
  path: '/',
  secret: 'xxx'
})

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

handler.on('error', err => {
  console.error('Error:', err.message)
})

handler.on('push', e => {
  try {
  const s = spawn('sh', ['./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) {}
})

这里几个点:

  • 'github-webhook-handler’ 库:建server很方便。
  • spawn:node端执行跨平台命令,spawn('sh', ['./run.sh'])可以执行run.sh
    • ./build.sh:执行的shell脚本
    • cwd:执行的目录
    • s.stdout:把shell输出打出来
  • payload:github webhook请求过来时带的数据对象,具体格式可以在webhook记录里看到

更新

shell的内容根据项目情况来,比如:

git reset --hard origin/master
git clean -f
git pull
npm install
npm run build

echo ‘build end'

试下效果

github webhook记录

image

node输出

image

此时刷新页面,代码已经更新了