使用GitHub的webhooks,开发人员可以创建许多有用的服务。从在Jenkins实例上触发CI(持续集成)作业到在云中配置机器,几乎都有无限的可能性。本教程将展示如何使用Python和Flask框架设置简单的持续部署(CD)服务。此示例中的持续部署服务是一个简单的Flask应用程序,它具有一个接受GitHub的webhookwebhook请求的REST端点。在验证每个请求都来自正确的GitHub存储库后,服务器将拉取更改拉取到存储库的本地副本。这样每次有新的提交推送到远程GitHub仓库,本地仓库就会自动更新。Flask网络服务用Flask构建一个小型网络服务非常简单。这里可以先看看项目的结构。├──app│├──__init__.py│└──webhooks.py├──requirements.txt└──wsgi.py首先,创建应用程序。应用程序代码位于app目录中。两个文件(__init__.py和webhooks.py)组成了Flask应用程序。前者包含创建Flask应用程序并向其添加配置的代码。后者具有端点逻辑。这是应用程序接收GitHub请求数据的地方。下面是app/__init__.py的内容:']=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保存自动更新的存储库路径。此代码使用FlaskBlueprintsFlaskBlueprints来组织应用程序的端点。使用蓝图对API进行逻辑分组,使应用程序更易于维护。这通常被认为是好的做法。下面是app/webhooks.py的内容:methods=['POST'])defhandle_github_hook():"""githubwebhook入口点"""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()ifhmac.compare_digest(hashhex,signature):repo=Repo(current_app.config.get('REPO_PATH'))origin=repo.remotes.originorigin.pull('--rebase')commit=request.json['after'][0:6]print('使用提交更新存储库{}'.format(commit))returnjsonify({}),200首先,代码创建一个新的蓝图webhook。然后它使用Flask路由将端点添加到蓝图。对/GitHubURL端点的任何POST请求都将调用此路由。验证请求当服务在此端点上收到请求时,首先它必须验证请求来自GitHub和正确的存储库。GitHub在请求的X-Hub-Signature标头中提供签名。签名由一个秘密(GITHUB_SECRET)、请求正文的HMAC十六进制摘要组成,并使用sha1进行哈希处理。为了验证请求,服务需要在本地计算签名并将其与请求标头中收到的签名进行比较。这可以通过hmac.compare_digest函数来完成。自定义挂钩逻辑现在可以在验证后处理请求。本教程使用GitPython模块与git存储库进行交互。GitPython模块中的Repo对象用于访问远程仓库origin。该服务从本地原始存储库中提取最新更改,并使用--rebase选项来避免合并问题。调试打印语句显示从请求正文收到的短提交哈希。此示例显示如何使用请求正文。有关请求正文中可用数据的更多信息,请参阅GitHub文档。***该服务返回了一个空的JSON字符串,状态代码为200。这用于告诉GitHub的webhook服务已收到请求。部署服务为了运行该服务,本示例使用gunicornWeb服务器。首先安装服务依赖项。在支持的Fedora服务器上,使用sudo运行此命令:sudodnfinstallpython3-gunicornpython3-flaskpython3-GitPython现在编辑gunicorn用于运行服务的wsgi.py文件:fromappimportcreate_appapplication=create_app()用于部署服务,使用使用以下命令克隆此git存储库或使用您自己的git存储库:gitclonehttps://github.com/cverna/github_hook_deployment.git/opt/下一步是配置服务所需的环境变量。运行这些命令:exportGITHUB_SECRET=asecretpassphraseusebygithubwebhookexportREPO_PATH=/opt/github_hook_deployment/本教程使用GitHub存储库作为webhook服务,但您可以根据需要使用不同的存储库。***,使用这些命令打开web服务:cd/opt/github_hook_deployment/gunicorn--bind0.0.0.0wsgi:application--reload这些选项将web服务的IP地址绑定到0.0.0.0,这意味着它将接受来自任何主机的请求。选项--reload确保在代码更改时重新启动Web服务。这就是持续部署的魔力所在。每次收到GitHub拉取时,都会拉取存储库的最新更新,gunicore会检测到这些更改并自动重启服务。*注意:*为了接收GitHub请求,Web服务必须部署在具有公共IP地址的服务器上。执行此操作的简单方法是使用您最喜欢的云提供商,如DigitalOcean、AWS、Linode等。本教程关于配置GitHub的最后一部分是配置GitHub以将webhook请求发送到Web服务。这是持续部署的关键。从GitHub存储库的设置中,选择Webhooks菜单,然后单击“添加Webhook”。输入以下信息:“PayloadURL”:服务的URL,例如
