Go學習之旅·一:實現github的自動鈎子


實現github的自動鈎子


最近在學習go,也寫了一些玩具放到自己的服務器中,但是感覺每次寫完在本地交叉編譯后上傳到服務器略顯麻煩,上傳代碼到服務器中編譯也是略顯麻煩,把編譯文件加入到git管理中會導致git包變大,拉取代碼變慢,特別是神秘之牆的存在會導致拉取github代碼很慢,所以就實現了一下github的自動鈎子,在服務器上自動編譯並完成自動部署,記錄一下實現的過程。

實現服務端

首先,我們需要准備一個供webhook調用的服務端,我這里用go實現了一個demo,更多功能請參考官方文檔

webhook 其實就是每當接受到push的時候,會向我們注冊的url中發送一條post請求,請求中的參數可以參考webhook的文檔


package main

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os/exec"
	"strings"
)

const Secret  = "AxkkeqzADO8WjkBT"
const HookShell  = "/data/hook.sh"

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		//我們這里只接收json的請求體
		if contentType := r.Header.Get("content-type"); contentType != "application/json" {
			throwError(w, "not json")
			return
		}

		bytes,err := ioutil.ReadAll(r.Body)
		if err != nil {
			throwError(w, fmt.Sprintln("body err", err))
			return
		}

		//首先應該對secret進行校驗
		signature := r.Header.Get("X-Hub-Signature")
		if len(signature) <= 0 {
			throwError(w, "signature empty")
			return
		}

		hash := hmac.New(sha1.New, []byte(Secret))
		hash.Write(bytes)
		sign := "sha1=" + hex.EncodeToString(hash.Sum(nil))
		if strings.Compare(sign, signature) != 0 {
			throwError(w, "signature error")
			return
		}


		var body map[string]interface{}
		if err := json.Unmarshal(bytes, &body); err != nil {
			throwError(w, fmt.Sprintln("Unmarshal err", err))
			return
		}

		//body里就已經獲取到我們想要的數據了, 在這里我們只拿取push的分支,更多參數參考可以參考文檔
		ref, ok := body["ref"].(string)
		if !ok {
			throwError(w, "!ok")
			return
		}
		//拿到的ref:refs/heads/master,我們只需要把前面截掉,就是我們想要的分支名
		branch := strings.TrimLeft(ref, "refs/heads/")

		//我們這里只對master分支進行自動部署
		if branch != "master" {
			w.WriteHeader(200)
			_,_ = w.Write([]byte("not update"))
			return
		}

		//我這里的部署是運行一個shell腳本,我們可以在這里寫自動更新和部署的邏輯
		if err := exec.Command(HookShell).Run(); err != nil {
			w.WriteHeader(500)
			_,_ = w.Write([]byte("deploy error"))
		}
	})

	_ = http.ListenAndServe(":49999", nil)
}

func throwError(w http.ResponseWriter, msg string)  {
	w.WriteHeader(400)
	_,_ = w.Write([]byte("bad request. " + msg))
}


配置webhook

部署完成后,我們需要在倉庫中添加一個webhook


在webhooks配置中,需要輸入鈎子的url,content-type這里我選擇application/json,secret這里是你的密鑰,然后我這里只需要對push操作進行響應。

配置完成后,提交代碼測試即可


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM