Python基于Webhook實現(xiàn)github自動化部署
一. 分析需求
1. 需求說明
在項目開發(fā)過程中,我們有時會頻繁的更新代碼, 流程大概為:
(1) 本地git push提交代碼至git托管平臺
(2) 登陸到部署有網(wǎng)站源碼的線上服務(wù)器
(3) cd到項目根目錄, 執(zhí)行g(shù)it pull 指令拉取最新代碼

整個流程純手動更新,每次耗時在1分鐘左右, 這樣一天下來,浪費了很多時間在這些瑣碎的事情上.
現(xiàn)在的需求是,在每次本地提交代碼后,線上服務(wù)器自動拉取最新代碼,完成部署更新.即所謂的自動化部署.
2. 方案
現(xiàn)在一些主流代碼托管平臺如github、 gitlab、git@osc 等均已提供webhook功能,在用戶push了代碼后,會自動回調(diào)一個您設(shè)定的http地址。 用戶可以自己根據(jù)不同的需求,來編寫自己的腳本程序(比如發(fā)郵件,自動部署等);目前,webhook支持多種觸發(fā)方式,如Push、 Tag Push、 Issue、評論、合并請求 等。
附webhook的簡介:
Webhook就是用戶通過自定義回調(diào)函數(shù)(callback)的方式來改變Web應(yīng)用的一種行為,這些回調(diào)函數(shù)可以由不是該Web應(yīng)用官方的第三方用戶或者開發(fā)人員來維護,修改。通過Webhook,你可以自定義一些行為通知到指定的URL去。Webhook的“自定義回調(diào)函數(shù)”通常是由一些事件觸發(fā)的,比如推送代碼到代碼庫或者博客下新增一個評論,源站點會為Webhook進行HTTP請求的URI配置。用戶通過配置,就可以使一個網(wǎng)站上的事件調(diào)用在另一個網(wǎng)站上表現(xiàn)出來,這些事件調(diào)用可以是任何事件,但通常應(yīng)用的是系統(tǒng)集成和消息通知。
方案流程:

所以自動部署主要實現(xiàn)方式就是:
- 修改代碼 push
- github(其他倉庫平臺)發(fā)送請求給你的網(wǎng)站服務(wù)器
- 網(wǎng)站服務(wù)器收到更新請求,執(zhí)行自動部署腳本
- 自動部署腳本執(zhí)行代碼拉取,打包,修改文件等動作完成網(wǎng)站的更新部署
二、具體實現(xiàn)
Github倉庫設(shè)置
在GitHub上需要更新的代碼倉庫添加webhooks, 在指定倉庫→settings→webhooks

編寫GitHub推送回調(diào)
python開啟web服務(wù)(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參數(shù)中
"""
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都是在倉庫的同一目錄下
開啟服務(wù)
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 服務(wù)器IP; # 配置域名
client_max_body_size 300M;
location / {
proxy_pass http://127.0.0.1:8989; #轉(zhuǎn)發(fā)本地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;
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python實現(xiàn)類似jQuery使用中的鏈式調(diào)用的示例
chained calls鏈式調(diào)用其實多是指一種方法鏈的程序?qū)懛?這里我們來看一下Python實現(xiàn)類似jQuery使用中的鏈式調(diào)用的示例,首先說明一下什么是鏈式調(diào)用:2016-06-06
python中json.dumps()和json.loads()的用法
json.dumps()和json.loads()?json.dumps()用于將字典形式轉(zhuǎn)換為字符串,下面這篇文章主要給大家介紹了關(guān)于python中json.dumps()和json.loads()用法的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-09-09
只用50行Python代碼爬取網(wǎng)絡(luò)美女高清圖片
第一次寫文章,技術(shù)不成熟之處望各位大神輕噴,今天教大家只用50行Python代碼爬取網(wǎng)絡(luò)美女圖片是怎么操作的,文中有非常詳細的代碼示例,對正在學(xué)習(xí)python的小伙伴們很有幫助哦,需要的朋友可以參考下2021-06-06
pytorch 實現(xiàn)多個Dataloader同時訓(xùn)練
這篇文章主要介紹了pytorch 實現(xiàn)多個Dataloader同時訓(xùn)練的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-05-05
Python 時間操作例子和時間格式化參數(shù)小結(jié)
這篇文章主要介紹了Python 時間操作例子,例如取前幾天、后幾天、前一月、后一月等,需要的朋友可以參考下2014-04-04

