zoukankan      html  css  js  c++  java
  • 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操作进行响应。

    配置完成后,提交代码测试即可

  • 相关阅读:
    企业应用的互联网化
    企业应用开发平台GAP平台
    技术有什么用?
    Samba服务器配置
    IT从业人员需要知道的10个小秘密
    在雪豹10.6.2(Mac OS X)上安装Oracle10g
    项目经理的职责
    通过堡垒机远程连接Windows Server
    MySQL:Data truncated for column 'last_apply_time' at row 1
    当有莫名其妙的错误里, 可以
  • 原文地址:https://www.cnblogs.com/zoujiejun96/p/12178663.html
Copyright © 2011-2022 走看看