[Gitlab]使用Webhook實現前端項目自動發佈

喜聞樂見的背景故事時間--承接[prerender-spa-plugin]--微型Vue項目的靜態化利器,官網上線以後,就開始琢磨,每次改動都得上服務器部署一下,是否是有點麻煩了,是時候該整個自動化部署惹:)而後就開始本身挖坑本身填啦。前端

本文將會涉及的內容--node

  • Webhook是啥?何時該使用它?
  • 該怎麼利用Webhook解放咱們的雙手?
  • 小結

Webhook是啥?何時該使用它?

以我司爲例,咱們團隊內部使用Gitlab做爲代碼倉庫,因此如下內容都是在Gitlab中進行實踐的,固然在Github上其實也是大同小異的。python

Webhook顧名思義,其實就是一鉤子。當咱們在Gitlab上作出某些特定操做時,能夠觸發鉤子,去進行一些咱們事先設定好的腳本,以達到某些特定功能(例如--前端項目自動發佈)。git

也許熟悉Gitlab的同窗會說了,這不就是CI嗎,爲何好好的CI放着不用要去搞webhook呢?確實,CI也能完成同樣的功能,可是也要結合業務實際情況而言。該項目並不是公司核心項目,跑CI的runner須要有Gitlab控制權限的同事幫忙配置,本着不騷擾同事的原則,我的認爲應該本身動手豐衣足食,既然有簡單便捷的webhook爲何不用呢?web

何時才應該去使用它呢?我的認爲至少要有這幾點:express

  • 項目不是一成不變的
  • 你是項目的負責人
  • 你有權限進入部署項目的服務器
  • 你能擠得出時間來踩坑

該怎麼利用Webhook解放咱們的雙手?

上圖是Gitlab中有關webhook的配置頁面,當咱們成功進行了[Trigger]內部的某些或某些操做時,好比Push events--成功push了一次代碼,不管是向哪一個分支push,均可以觸發hook......安全

以後Gitlab將會自動的替咱們向URL中的連接發去POST請求,這裏能夠是腳本也能夠是服務,只要可以成功接收來自Gitlab的請求便可。在本次實踐中,我起了一個node服務來幫助完成自動化部署。服務器

那麼就有一個問題了,請求那個URL就會觸發node服務中的部署流程,那麼萬一有人一直在玩那個接口,會不會把服務搞掛或是把網站搞掛呢?還真有可能...因此Gitlab給了咱們設置Secret Token的機會,咱們檢測到請求有帶有這段特殊的token才能認爲本次請求是安全可接受的。微信

It will be sent with the request in the X-Gitlab-Token HTTP header.app

這裏須要注意一下的是,實際上咱們並不會找到X-Gitlab-Token這個請求頭,咱們只會匹配到x-gitlab-token這個字段,別問我爲何知道的,你們注意避坑就好:)

下面講講在服務器上咱們是怎麼接收Gitlab的請求而且執行部署的--

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`)
})
複製代碼

在項目部署的機器上,跑了這個簡單的node服務,大意是當Gitlab POST一個請求過來時,咱們進行鑑權,隨後經過node去執行一段命令行語句,根據執行的結果調用不一樣的方法。這裏有幾個坑點--

node服務搭建

貪圖方便,依賴了一下express,固然咱們是能夠用http模塊來完成這些操做的,另外監聽端口的時候須要確認當前端口是否可被外網訪問。

node執行服務器命令行

咱們可使用node中'child_process'模塊的exec方法來執行命令行語句,將定義好的命令行語句字符串傳入exec方法做爲第一個參數便可,後面一個參數則是執行結果的回調,依照業務須要設計便可。

發佈鑑權&&發佈狀態

經過Gitlab請求中帶來的token來鑑定本次請求是否可以觸發下面的部署,而且須要設定一個"發佈中"的狀態,防止屢次請求帶來的各類沒法預知的後果。

上面的代碼只是最基本的發佈服務,在裏面能夠作任何事,發佈完成或失敗的各類通知,甚至還能夠對提交的代碼進行檢測,假若不符合規範還能夠拒絕本次自動部署......只要想踩坑,一切皆有可能~這樣反映出webhook的靈活,只需對git作一個簡單的操做,就能夠推倒多米諾骨牌,完成一些意想不到的操做。

小結

本切圖仔第一次踩這方面的坑,但願對萌新們有所幫助,也但願大大們輕拍。接下來,可能會有一個基於python的自動部署完成後微信通知腳本,敬請期待,固然也可能沒有:)畢竟只是個切圖仔,搬完該搬的磚就到睡點了> <

相關文章
相關標籤/搜索