利用Github在倉庫進行操做時,能夠經過配置webhook向服務器發送請求,在服務器端接到請求後,使用腳原本自動進行git pull操做。html
圖片來源:Github的webhook觸發vps上的腳本node
經過執行git
npm i -g github-webhook-handler
來安裝 github-webhook-handler 中間件github
新建文件 webhook.js
web
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。服務器
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
在使用腳本以前,先要對網站根目錄作一些處理
# 打開網站根目錄 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:
npm i pm2 -g
運行webhook.js
pm2 start webhook.js
進入須要自動部署的項目的github地址添加webhook,進入Settings設置頁面,點擊左側的 Webhooks