快來學(xué)習(xí)下webhook吧!超級簡單易學(xué)

1. Webhook是啥?
簡單而言,webhook就是一個監(jiān)聽的鉤子,監(jiān)聽你push你的代碼到github倉庫之后,發(fā)起一個請求。這個請求要請求哪里交給你設(shè)置要。

主要流程

git push xxx 本地代碼提交至遠(yuǎn)程github倉庫
github倉庫收到push后進行回調(diào),發(fā)post( Payload url 是來自webhooks的配置)請求
基于 Payload url 的服務(wù)根據(jù)傳回來的信息進行提取,拉取最新代碼并重新構(gòu)建項目
可以看到,我們只需把代碼提交到github倉庫即可,不用再上服務(wù)器進行一些列的操作了
在這里插入圖片描述
2. webhook有什么作用呢?
目前我發(fā)現(xiàn)的我們公司主要是用于 監(jiān)聽到開發(fā)者 push代碼到倉庫之后就 發(fā)送消息到企業(yè)微信群里。如下圖所示:
在這里插入圖片描述
完成自動化部署
3.配置webhook超簡單
來到你的倉庫,點擊setting

在這里插入圖片描述
然后選中左邊的webhook,就可以配置了

在這里插入圖片描述
4.主要配置四部分:
Payload URL 回調(diào)服務(wù)的地址,就是你想請求的一個接口的地址,請求方式是POST;

Content type 回調(diào)請求頭,建議JSON格式;

Secret 為了做安全校驗,設(shè)置后會在請求 header 中增加如下兩個屬性,用來區(qū)分請求的來源,避免暴露的請求被惡意訪問;

X-Hub-Signature: ...
X-Hub-Signature-256:...
最后我們選擇由哪些事件來觸發(fā)webhook回調(diào),push event(代碼推送事件)、everything(所有事件)、某些特定事件三種。

配置完成后,嘗試提交代碼下,然后從Recent Deliveries中你會發(fā)現(xiàn)有調(diào)用webhook的記錄。

5.實現(xiàn)自動化部署
我們用node簡單地搭建一個服務(wù)器

下面講講在服務(wù)器上我們是怎么接收Gitlab的請求并且執(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的請求URL是我們的deploy接口時,當(dāng)webhook監(jiān)聽到我們push代碼之后,就會請求deploy接口,然后執(zhí)行接口里面的邏輯,然后自動化部署就是我們在接口里寫好的cmdStr字符串了。

6.實現(xiàn)企業(yè)微信機器人報告
企業(yè)微信的配置其實更簡單,我們先創(chuàng)建一個群組,在群組右鍵有個添加機器人選項,添加成功后會生成webhook地址。我們只要向這個地址發(fā)送POST請求,群組內(nèi)就會收到推送消息。

在這里插入圖片描述
消息內(nèi)容支持文本(text)、markdown(markdown)、圖片(image)、圖文(news)四種消息類型,而且還支持在群內(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)點事"
        }
   }'

直接請求 url 發(fā)現(xiàn)消息推送成功,說明配置的沒問題。

所以我們可以這樣實現(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)點事"
        }
     })
  } catch (error) {
    console.log(error);
  }
})

app.listen(1234, '0.0.0.0', function () {
    console.log(`listening on port 1234`)
})
看,基本就是這樣實現(xiàn)啦,夠簡單吧,(代碼只是寫個大概,并不完整)。

快去給你的倉庫配置下webhook吧。

作者:事業(yè)有成的張啦啦


歡迎關(guān)注微信公眾號 :前端陽光