快來(lái)學(xué)習(xí)下webhook吧!超級(jí)簡(jiǎn)單易學(xué)
1. Webhook是啥?
簡(jiǎn)單而言,webhook就是一個(gè)監(jiān)聽(tīng)的鉤子,監(jiān)聽(tīng)你push你的代碼到github倉(cāng)庫(kù)之后,發(fā)起一個(gè)請(qǐng)求。這個(gè)請(qǐng)求要請(qǐng)求哪里交給你設(shè)置要。
主要流程
git push xxx 本地代碼提交至遠(yuǎn)程github倉(cāng)庫(kù)
github倉(cāng)庫(kù)收到push后進(jìn)行回調(diào),發(fā)post( Payload url 是來(lái)自webhooks的配置)請(qǐng)求
基于 Payload url 的服務(wù)根據(jù)傳回來(lái)的信息進(jìn)行提取,拉取最新代碼并重新構(gòu)建項(xiàng)目
可以看到,我們只需把代碼提交到github倉(cāng)庫(kù)即可,不用再上服務(wù)器進(jìn)行一些列的操作了
2. webhook有什么作用呢?
目前我發(fā)現(xiàn)的我們公司主要是用于 監(jiān)聽(tīng)到開(kāi)發(fā)者 push代碼到倉(cāng)庫(kù)之后就 發(fā)送消息到企業(yè)微信群里。如下圖所示:
完成自動(dòng)化部署
3.配置webhook超簡(jiǎn)單
來(lái)到你的倉(cāng)庫(kù),點(diǎn)擊setting
然后選中左邊的webhook,就可以配置了
4.主要配置四部分:
Payload URL 回調(diào)服務(wù)的地址,就是你想請(qǐng)求的一個(gè)接口的地址,請(qǐng)求方式是POST;
Content type 回調(diào)請(qǐng)求頭,建議JSON格式;
Secret 為了做安全校驗(yàn),設(shè)置后會(huì)在請(qǐng)求 header 中增加如下兩個(gè)屬性,用來(lái)區(qū)分請(qǐng)求的來(lái)源,避免暴露的請(qǐng)求被惡意訪(fǎng)問(wèn);
X-Hub-Signature: ...
X-Hub-Signature-256:...
最后我們選擇由哪些事件來(lái)觸發(fā)webhook回調(diào),push event(代碼推送事件)、everything(所有事件)、某些特定事件三種。
配置完成后,嘗試提交代碼下,然后從Recent Deliveries中你會(huì)發(fā)現(xiàn)有調(diào)用webhook的記錄。
5.實(shí)現(xiàn)自動(dòng)化部署
我們用node簡(jiǎn)單地搭建一個(gè)服務(wù)器
下面講講在服務(wù)器上我們是怎么接收Gitlab的請(qǐng)求并且執(zhí)行部署的--
const exec = require('child_process').exec
const express = require('express')
const app = express()
let isLocking = false
app.post('/deploy', function (req, res) {
let headers = req.headers
let cmdStr = 'cd ... && git fetch origin && ...'
if (!isLocking && headers['x-gitlab-token'] === 'xxx') {
isLocking = true
exec(cmdStr, function (err, stdout, stderr) {
if (err) {
// ...
console.log('error:' + stderr);
} else {
// ...
console.log(stdout)
isLocking = false
}
})
}
// ......
})
app.listen(1234, '0.0.0.0', function () {
console.log(`listening on port 1234`)
})
可以看到,當(dāng)我們配置webhook的請(qǐng)求URL是我們的deploy接口時(shí),當(dāng)webhook監(jiān)聽(tīng)到我們push代碼之后,就會(huì)請(qǐng)求deploy接口,然后執(zhí)行接口里面的邏輯,然后自動(dòng)化部署就是我們?cè)诮涌诶飳?xiě)好的cmdStr字符串了。
6.實(shí)現(xiàn)企業(yè)微信機(jī)器人報(bào)告
企業(yè)微信的配置其實(shí)更簡(jiǎn)單,我們先創(chuàng)建一個(gè)群組,在群組右鍵有個(gè)添加機(jī)器人選項(xiàng),添加成功后會(huì)生成webhook地址。我們只要向這個(gè)地址發(fā)送POST請(qǐng)求,群組內(nèi)就會(huì)收到推送消息。
消息內(nèi)容支持文本(text)、markdown(markdown)、圖片(image)、圖文(news)四種消息類(lèi)型,而且還支持在群內(nèi)@群成員,下邊以文本格式做示范。
curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=145a516a-dd15-421f-97a3-ba3bf1479369' \
-H 'Content-Type: application/json' \
-d '
{
"msgtype": "text",
"text": {
"content": "你好,我是程序員內(nèi)點(diǎn)事"
}
}'
直接請(qǐng)求 url 發(fā)現(xiàn)消息推送成功,說(shuō)明配置的沒(méi)問(wèn)題。
所以我們可以這樣實(shí)現(xiàn):
const exec = require('child_process').exec
const express = require('express')
const app = express()
let isLocking = false
app.post('/deploy', function (req, res) {
try {
const content = JSON.parse(req.body.payload) ;
const name = content.pusher.name;
const message = content.before;
axios.post('https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=145a516a-dd15-421f-97a3-ba3bf1479369',data: {
"msgtype": "text",
"text": {
"content": "你好,我是程序員內(nèi)點(diǎn)事"
}
})
} catch (error) {
console.log(error);
}
})
app.listen(1234, '0.0.0.0', function () {
console.log(`listening on port 1234`)
})
看,基本就是這樣實(shí)現(xiàn)啦,夠簡(jiǎn)單吧,(代碼只是寫(xiě)個(gè)大概,并不完整)。
快去給你的倉(cāng)庫(kù)配置下webhook吧。
作者:事業(yè)有成的張啦啦
歡迎關(guān)注微信公眾號(hào) :前端陽(yáng)光