使用Python处理github webhook推送

我们使用 hexo 搭建一个博客,一般是放到自己的 vps 服务器上,使用 github 保存的博客内容。那么如果想实现本地新加了一篇博客,推送到 github 上,然后 vps 上的博客内容能够及时更新,就可以借助 githubwebhook 功能。

GitHub Webhooks 是一种机制,用于将 GitHub 上的事件通知发送到外部服务器。当发生特定的事件(例如,代码推送、PR 创建、发布等)时,GitHub 会向你指定的 URL 发送一个 HTTP POST 请求,包含有关该事件的详细信息。Webhook 常用于自动化工作流,比如自动部署、CI/CD 集成、通知等。

Webhook 使用步骤

1. 创建 Webhook

要在 GitHub 中设置 Webhook,你需要拥有一个仓库的管理权限。按照以下步骤创建 Webhook:

  1. 进入 GitHub 仓库
    打开你需要设置 Webhook 的 GitHub 仓库页面。

  2. 打开设置
    点击仓库页面右上角的 Settings 按钮。

  3. 选择 Webhooks
    在左侧栏中,找到 Webhooks 并点击。

  4. 添加 Webhook
    点击右上角的 Add webhook 按钮。

2. 配置 Webhook

在创建 Webhook 时,你需要配置以下选项:

  • Payload URL
    这是接收 Webhook 请求的服务器 URL。GitHub 将事件信息发送到此 URL。这个 URL 是你自己搭建的服务器或者第三方服务提供的接口(如 CI/CD 系统的 API)。

    例如:

    1
    http://your-server.com/webhook
  • Content type
    选择发送的内容类型,通常选择 application/json。GitHub 会以 JSON 格式发送事件数据。

  • Secret
    为了验证请求的安全性,可以设置一个 secret 字符串。每次 GitHub 发送请求时,都会用这个 secret 来进行签名。你可以在接收端的服务器上验证签名,确保请求是来自 GitHub。

  • Which events would you like to trigger this webhook?
    选择哪些 GitHub 事件会触发这个 Webhook。常见的事件包括:

    • Push:当有代码推送到仓库时触发。
    • Pull Request:当有 PR 创建、合并等时触发。
    • Issues:当创建、更新或关闭 issue 时触发。
    • Release:当发布新版本时触发。

    你可以选择一个或多个事件,甚至选择 Just the push eventSend me everything

  • Active
    确保启用 Active 选项,这样 Webhook 才会被激活。

点击 Add webhook 按钮完成配置。

3. 处理 Webhook 请求

GitHub 会向你指定的 URL 发送 HTTP POST 请求,数据格式为 JSON。你可以在服务器端编写代码来接收和处理这些请求。

示例: 用 Python 编写一个简单的 Webhook 接收器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
from flask import Flask, request, jsonify
import hashlib
import hmac
import json

app = Flask(__name__)

# GitHub Webhook secret(你需要在 GitHub Webhook 配置时设置)
WEBHOOK_SECRET = 'xxxxxx'

# 验证 GitHub 请求的签名
def verify_signature(payload, signature):
# GitHub 发来的签名是以 `sha1=` 开头的,所以去掉前缀
sha1_signature = signature.split('=')[1]
# 计算请求的哈希值
computed_signature = hmac.new(WEBHOOK_SECRET.encode(), payload, hashlib.sha1).hexdigest()
return True

@app.route('/githubwebhook', methods=['POST'])
def github_webhook():
# 获取 GitHub 发来的请求头中的签名
signature = request.headers.get('X-Hub-Signature')

if not signature:
return 'Signature missing', 400

# 获取请求的原始数据(即 payload)
payload = request.get_data()

# 验证签名
if not verify_signature(payload, signature):
return 'Invalid signature', 400

# 解析 Webhook 内容
event = request.headers.get('X-GitHub-Event')
data = json.loads(payload)

# 处理不同类型的事件
if event == 'push':
print(f"Received push event: {data}")
# 你可以在这里处理 push 事件,例如构建、部署等
repository_name = data['repository']['name']
if repository_name == '你的项目名称':
//可以执行一段自己的脚本,这里最好是异步执行
subprocess.run(['bash','xxx.sh'], capture_output=True, text=True)
elif event == 'pull_request':
print(f"Received pull request event: {data}")
# 处理 pull request 事件
else:
print(f"Received {event} event: {data}")

# 返回响应
return jsonify({'status': 'success'}), 200

if __name__ == '__main__':
# 启动 Flask 服务器
app.run(host='0.0.0.0', port=7777, debug=True)

在这个例子中,Flask 用来接收和处理 GitHub Webhook 请求,X-Hub-Signature 用来验证请求的有效性(如果设置了 Secret)。然后,检查事件类型(比如 pushpull_request),并根据事件类型执行相应的脚本。

hexo博客部署脚本示例:

1
2
3
4
5
6
7
8
9
10
#!/bin/bash 
echo "start cd /home/admin/xxx"
cd /home/admin/xxx
echo "start git pull"
git pull
echo "start hexo clean"
hexo clean
echo "start hexo g"
hexo g
echo "process success"

5. 测试 Webhook

webhook 创建之后,github 会向 Payload URL 发送一个ping消息,你可以测试是服务端脚本否正常工作。

测试正常后,就可以本地提交内容到github,然后观察vps是否同步更新了内容。

总结

通过 Webhook,你可以将 GitHub 与 存放博客的 VPS 服务器无缝集成,创建自动化部署工作流,提升效率。


使用Python处理github webhook推送
https://wydpp.com/posts/1ed10035.html
作者
老段
发布于
2024年12月13日
许可协议