VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • 使用 GitHub 和 Python 实现持续部署

借助 GitHub 的网络钩子webhook,开发者可以创建很多有用的服务。从触发一个 Jenkins 实例上的 CI(持续集成) 任务到配置云中的机器,几乎有着无限的可能性。这篇教程将展示如何使用 Python 和 Flask 框架来搭建一个简单的持续部署(CD)服务。

 

在这个例子中的持续部署服务是一个简单的 Flask 应用,其带有接受 GitHub 的网络钩子webhook请求的 REST 端点endpoint。在验证每个请求都来自正确的 GitHub 仓库后,服务器将拉取pull更改到仓库的本地副本。这样每次一个新的提交commit推送到远程 GitHub 仓库,本地仓库就会自动更新。

 

Flask web 服务

用 Flask 搭建一个小的 web 服务非常简单。这里可以先看看项目的结构。

1
2
3
4
5
├── app
│   ├── __init__.py
│   └── webhooks.py
├── requirements.txt
└── wsgi.py

首先,创建应用。应用代码在 app 目录下。

两个文件(__init__.py 和 webhooks.py)构成了 Flask 应用。前者包含有创建 Flask 应用并为其添加配置的代码。后者有端点endpoint逻辑。这是该应用接收 GitHub 请求数据的地方。

这里是 app/__init__.py 的内容:

1
2
3
4
5
6
7
8
9
10
import os
from flask import Flask
from .webhooks import webhook
def create_app():
 """ Create, configure and return the Flask application """
  app = Flask(__name__)
  app.config['GITHUB_SECRET'= os.environ.get('GITHUB_SECRET')
  app.config['REPO_PATH'= os.environ.get('REPO_PATH')
  app.register_blueprint(webhook)
  return(app)

该函数创建了两个配置变量:

GITHUB_SECRET 保存一个密码,用来认证 GitHub 请求。

REPO_PATH 保存了自动更新的仓库路径。

这份代码使用Flask 蓝图Flask Blueprints来组织应用的端点endpoint。使用蓝图可以对 API 进行逻辑分组,使应用程序更易于维护。通常认为这是一种好的做法。

这里是 app/webhooks.py 的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import hmac
from flask import request, Blueprint, jsonify, current_app 
from git import Repo
webhook = Blueprint('webhook', __name__, url_prefix='')
@webhook.route('/github', methods=['POST']) 
def handle_github_hook(): 
 """ Entry point for github webhook """
  signature = request.headers.get('X-Hub-Signature'
  sha, signature = signature.split('=')
  secret = str.encode(current_app.config.get('GITHUB_SECRET'))
  hashhex = hmac.new(secret, request.data, digestmod='sha1').hexdigest()
  if hmac.compare_digest(hashhex, signature): 
    repo = Repo(current_app.config.get('REPO_PATH')) 
    origin = repo.remotes.origin 
    origin.pull('--rebase')
    commit = request.json['after'][0:6]
    print('Repository updated with commit {}'.format(commit))
  return jsonify({}), 200

相关教程