使用Github的 WebHooks 進行網站自動化部署

原理

利用Github在倉庫進行操做時,能夠經過配置webhook向服務器發送請求,在服務器端接到請求後,使用腳原本自動進行git pull操做。html

image

圖片來源:Github的webhook觸發vps上的腳本node

構建 Webhook 服務

經過執行git

npm i -g github-webhook-handler

來安裝 github-webhook-handler 中間件github

新建文件 webhook.jsweb

var http = require('http')
var createHandler = require('github-webhook-handler')
var handler = createHandler({ path: '/', secret: 'root' })
// 上面的 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(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);
    run_cmd('sh', ['./deploy.sh',event.payload.repository.name], function(text){ console.log(text) });
})

其中shell

var handler = createHandler({ path: '/', secret: 'root' })

secret 字段爲 Github 中設置的,須要與這裏相對應npm

注意,在運行的時候若是提示 github-webhook-handler is not defined 未找到 ,能夠在目錄中執行 npm link github-webhook-handler

參考地址:利用Github的Webhook進行靜態網站的自動化部署bash

同一服務多個 webhook

當你有多個倉庫須要自動部署時,能夠在一個服務上開啓多個 webhook。服務器

var http = require('http')
var createHandler = require('node-github-webhook')
var 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)
  })
}
同一服務多個webhook時,最終你的payload URL 則爲: http:/yourdomain:7777/app1 或者 http:/yourdomain:7777/app2 ,注意我在實踐過程當中發現,不能使用 / 目錄,會沒法監聽到 webhook。

參考地址:https://github.com/rvagg/gith...app

完成 shell 腳本

在使用腳本以前,先要對網站根目錄作一些處理

# 打開網站根目錄
cd /home/wwwroot/domain.com
# 採用 Git 文件控制
git init
# 添加遠程 Git 倉庫地址
git remote add origin https://xx.git

參考地址:
How do I force 「git pull」 to overwrite local files?

而後再建立 deploy.sh,與 webhook.js 在同一個目錄下

#!/bin/bash
# 網站的根目錄
WEB_PATH='/home/wwwroot/domain.com'
 
echo "start deployment"
cd $WEB_PATH
echo "fetching from remote..."
# 爲了不衝突,強制更新本地文件
git fetch --all
git reset --hard origin/master
echo "done"
因爲 Linux 文件權限問題,可能沒法執行,建議先執行 chmod 777 ./deploy.sh

使用pm2進行進程守護

安裝pm2:

npm i pm2 -g

運行webhook.js

pm2 start webhook.js

進入Gtihub後臺進行設置

進入須要自動部署的項目的github地址添加webhook,進入Settings設置頁面,點擊左側的 Webhooks

image

原文地址:使用Github的-WebHooks-進行網站自動化部署

相關文章
相關標籤/搜索