1. 程式人生 > 程式設計 >Python基於Webhook實現github自動化部署

Python基於Webhook實現github自動化部署

一. 分析需求

1. 需求說明

在專案開發過程中,我們有時會頻繁的更新程式碼,流程大概為:

(1) 本地git push提交程式碼至git託管平臺

(2) 登陸到部署有網站原始碼的線上伺服器

(3) cd到專案根目錄,執行git pull 指令拉取最新程式碼

Python基於Webhook實現github自動化部署

整個流程純手動更新,每次耗時在1分鐘左右,這樣一天下來,浪費了很多時間在這些瑣碎的事情上.

現在的需求是,在每次本地提交程式碼後,線上伺服器自動拉取最新程式碼,完成部署更新.即所謂的自動化部署.

2. 方案

現在一些主流程式碼託管平臺如github、 gitlab、git@osc 等均已提供webhook功能,在使用者push了程式碼後,會自動回撥一個您設定的http地址。 使用者可以自己根據不同的需求,來編寫自己的指令碼程式(比如發郵件,自動部署等);目前,webhook支援多種觸發方式,如Push、 Tag Push、 Issue、評論、合併請求 等。

附webhook的簡介:

Webhook就是使用者通過自定義回撥函式(callback)的方式來改變Web應用的一種行為,這些回撥函式可以由不是該Web應用官方的第三方使用者或者開發人員來維護,修改。通過Webhook,你可以自定義一些行為通知到指定的URL去。Webhook的“自定義回撥函式”通常是由一些事件觸發的,比如推送程式碼到程式碼庫或者部落格下新增一個評論,源站點會為Webhook進行HTTP請求的URI配置。使用者通過配置,就可以使一個網站上的事件呼叫在另一個網站上表現出來,這些事件呼叫可以是任何事件,但通常應用的是系統整合和訊息通知。

方案流程:

Python基於Webhook實現github自動化部署

所以自動部署主要實現方式就是:

- 修改程式碼 push

- github(其他倉庫平臺)傳送請求給你的網站伺服器

- 網站伺服器收到更新請求,執行自動部署指令碼

- 自動部署指令碼執行程式碼拉取,打包,修改檔案等動作完成網站的更新部署

二、具體實現

Github倉庫設定

在GitHub上需要更新的程式碼倉庫新增webhooks,在指定倉庫→settings→webhooks

Python基於Webhook實現github自動化部署

編寫GitHub推送回調

python開啟web服務(hook.py)

import hmac
import os
from flask import Flask,request,jsonify

app = Flask(__name__)
# github中webhooks的secret
github_secret = 'xxxxxxxx'

def encryption(data):
  key = github_secret.encode('utf-8')
  obj = hmac.new(key,msg=data,digestmod='sha1')
  return obj.hexdigest()

@app.route('/hook',methods=['POST'])
def post_data():
  """
  github加密是將post提交的data和WebHooks的secret通過hmac的sha1加密,放到HTTP headers的
  X-Hub-Signature引數中
  """
  post_data = request.data
  token = encryption(post_data)
  # 認證簽名是否有效
  signature = request.headers.get('X-Hub-Signature','').split('=')[-1]
  if signature != token:
    return "token認證無效",401
  # 執行shell指令碼,更新程式碼
  os.system('sh deploy.sh')
  return jsonify({"status": 200})

if __name__ == '__main__':
  app.run(port=8989)

編寫shell指令碼(deploy.sh)

cd "$(dirname "$0")"
echo '--------Git pull------------'
git pull
echo '-----Already up-to-date------'
echo '----- restart supervision-----'
supervisorctl restart blog
echo '----- reload nginx-----'
nginx -s reload

注意: 此次部署的hook.py 和deploy.sh都是在倉庫的同一目錄下

開啟服務

supervisor部署webhook

[program:webhook]
directory=/data/wwwroot/docs
command=/home/dukenan/.envs/flask_py3/bin/python3 hook.py
autostart=true
autorestart=false
startsecs=1
;使用root賬戶
user=root
stderr_logfile=/etc/supervisor/logs/webhooks/stderr.log 
stdout_logfile=/etc/supervisor/logs/webhooks/stdout.log 
redirect_stderr=true
loginfo=info

部署NGINX的參考

server {
  listen 80; 
  server_name 伺服器IP; # 配置域名
  client_max_body_size 300M;
  location / { 
    proxy_pass http://127.0.0.1:8989; #轉發本地8989埠
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }  
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。