前言
Github或者Gitlab的Webhooks,允許使用者訂閱特定的事件,如commit, push,兩者不盡相同,但本質差不太多。Github的可以參看github webhooks,Gitlab可以參看gitlab webhooks。
本文後續都以Github為例進行講解,Gitlab相關可以參考相關内容。
自動部署腳本
Webhooks的作用就是在特定的事件執行的時候觸發自定義的動作。本質上,Github的Webhooks觸發後,會給相應的URL(自行設定,後面會講解)發送POST請求,請求頭中含有event等相應的資訊。
而正确響應後的事件,比如push完之後,觸發自動部署腳本,現在我們來寫一個簡單的腳本。
-
#!/bin/bash
-
PROJECT_DIR = 'path-to-your-project'
-
echo 'start'
-
cd $PROJECT_DIR
-
echo 'pull code'
-
git reset --hard origin/master && git clean -f
-
git pull && git checkout master
-
echo 'run npm script'
-
npm run build
-
echo 'finished'
bash
腳本大概的作用就是cd到項目目錄,拉取最新的代碼,build代碼(該步驟不一定需要,如果你的代碼直接可以上測試/生産環境)。你必須保證,腳本中涉及的環境變量是可用的,比如
git
,
npm
等等。
我們把這個腳本命名為
deploy.sh
,暫時放在一邊,等需要的時候再用。
設定Webhooks
在你的項目中,通過
Settings
->
Webhooks
->
Add webhook
進入webhook設定頁面。我們以下都以push事件為例。
Payload URL
就是push之後,請求的url,我們這是
https://example.com/app
。
Content type
目前有兩種,根據server提供的來寫,我們選擇json格式的,因為後面的server使用的是json的。
Secret
就是密碼了,後面校驗的時候需要用到。
events
就是觸發的事件清單,我們選push就行了,可以選擇全部事件(第二個選項),也可以根據需要選擇(第三個選項)。個人建議最好是根據需要去選擇,不然會發送很多無謂的請求,加重伺服器的壓力。
然後就是處理請求的邏輯了,目前Github上有很多處理的handler。對于前端,當然是node的最熟悉,可以采用github-webhook-handler,但是這個單個webhook處理比較友善,多個會比較麻煩,是以這裡采用的就是我自己撸的一個支援多個webhooks的node-github-webhook。
安裝
-
npm install node-github-webhook --save
入口檔案app.js
-
var http = require('http')
-
var createHandler = require('node-github-webhook')
-
var handler = createHandler({ path: '/app', secret: 'appsecret' }) // single handler
-
function execFunc(content) {
-
var exec = require('child_process').exec
-
exec(content, function(error, stdout, stderr) {
-
if (error) {
-
console.error('exec error:' + error)
-
return
-
}
-
console.log('stdout:' + stdout)
-
console.log('stderr:' + stderr)
-
})
-
}
-
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
-
)
-
execFunc('sh ./deploy.sh')
-
})
js
path
就是前面
Payload URL
的内容,切記,是不包含host的,
secret
就是自己設定的密碼。
這裡為了友善,寫的是單個webhook的設定,如果你有多個項目,設定請參考這個。
守護程式
理論上,現在就可以運作了。
-
node app.js
但是,現在的node-github-webhook遇到錯誤是直接抛錯的,會終止程式的進行,是以最好采用守護程序去運作,如
pm2
,
forever
,我這采用了
pm2
。
pm2 start app.js
反向代理
現在程式是在7777端口跑的,需要Ngnix反向代理到80端口。這裡就不展開了。如果不想做,可以直接把
Payload URL
設定成
https://example.com:7777/app
,就是看起來不夠優雅。
結果
一般來說,如果成功了的話,你的代碼就已經更新了。如果你需要看具體的請求内容和傳回結果,可以在
Webhooks
裡的
Recent Deliveries
檢視每次請求的内容。
本文連結:https://excaliburhan.com/post/add-webhooks-to-your-project.html
-- EOF --