一、准备服务器环境

sudo apt update
sudo apt install git

Python 虚拟环境:

sudo apt install python3-venv
sudo mkdir -p /opt/gitee-webhook/
cd /opt/gitee-webhook/
python3 -m venv venv
source venv/bin/activate

此时命令行前应显示 (venv)

在虚拟环境中安装 Python 依赖(因为有些服务器会有保护机制,只能用虚拟环境):

pip install Flask waitress

克隆你的 Gitee 仓库到服务器:

cd /var/www/
git clone git@gitee.com:your_username/your_repo.git your_project_directory_name

ls -la,确保能看到 .git 目录

二、创建 WebHook 接收脚本

sudo nano /opt/gitee-webhook/webhook_receiver.py

输入:

# /opt/gitee-webhook/webhook_receiver.py

from flask import Flask, request, jsonify
import subprocess
import os
import hmac
import hashlib
import logging

app = Flask(__name__)

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# 配置项
# !!! 替换为你的 Git 仓库在服务器上的绝对路径
REPO_PATH = "/var/www/your-project"
# !!! 替换为你将在 Gitee WebHook 设置中填写的密码
WEBHOOK_SECRET = "YOUR_GITEE_WEBHOOK_SECRET"

@app.route('/webhook', methods=['POST'])
def webhook():
logging.info("Received a webhook request.")

# 1. 验证请求来源 (使用 Gitee WebHook 密码)
gitee_token = request.headers.get('X-Gitee-Token')
if gitee_token != WEBHOOK_SECRET:
logging.warning(f"Invalid X-Gitee-Token: {gitee_token}")
return jsonify({"message": "Invalid token"}), 403
logging.info("X-Gitee-Token verified successfully.")

# 2. 检查事件类型 (只处理 Push 和 Tag Push)
event = request.headers.get('X-Gitee-Event')
if event not in ['Push Hook', 'Tag Push Hook']:
logging.info(f"Ignoring event type: {event}")
return jsonify({"message": f"Event type {event} ignored"}), 200
logging.info(f"Processing event type: {event}")

# 3. 执行 Git 操作 (重置并拉取 - 如果需要完全覆盖本地)
try:
os.chdir(REPO_PATH)
logging.info(f"Executing git reset --hard origin/main and git pull in {REPO_PATH}...")

# 确保在正确的远程分支上 (例如 master 或 main)
# 替换 'master' 为你的主分支名称
result_reset = subprocess.run(['git', 'reset', '--hard', 'origin/main'], capture_output=True, text=True, check=True)
logging.info(f"Git reset --hard successful: {result_reset.stdout}")
if result_reset.stderr:
logging.warning(f"Git reset --hard had stderr output: {result_reset.stderr}")

# 然后执行普通的 git pull (此时通常会是 fast-forward)
result_pull = subprocess.run(['git', 'pull'], capture_output=True, text=True, check=True)
logging.info(f"Git pull successful: {result_pull.stdout}")
if result_pull.stderr:
logging.warning(f"Git pull had stderr output: {result_pull.stderr}")

return jsonify({"message": "Git reset and pull successful", "output": result_pull.stdout}), 200
except subprocess.CalledProcessError as e:
logging.error(f"Git operation failed with exit code {e.returncode}: {e.stderr}")
return jsonify({"message": "Git operation failed", "error": e.stderr}), 500
except FileNotFoundError:
logging.error(f"Git command not found. Ensure Git is installed and in PATH for user running the service.")
return jsonify({"message": "Git command not found"}), 500
except Exception as e:
logging.error(f"An unexpected error occurred: {e}")
return jsonify({"message": "An unexpected error occurred", "error": str(e)}), 500

三、配置 Systemd 服务

sudo nano /etc/systemd/system/gitee-webhook.service

输入:

[Unit]
Description=Gitee Webhook Receiver
After=network.target

[Service]
User=www-data
WorkingDirectory=/opt/gitee-webhook
ExecStart=/opt/gitee-webhook/venv/bin/python /opt/gitee-webhook/webhook_receiver.py
Restart=always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=gitee-webhook

[Install]
WantedBy=multi-user.target

确保 www-data 用户对 /opt/gitee-webhook/ 目录及其内容有读取和执行权限

sudo chown -R www-data:www-data /opt/gitee-webhook/
sudo chmod -R u+rwX,go+rX /opt/gitee-webhook/

确保 www-data 用户对你的 Git 仓库目录有写入权限

sudo chown -R www-data:www-data /var/www/your_project_directory_name/

重载 Systemd、启动服务并设置开机自启:

sudo systemctl daemon-reload
sudo systemctl start gitee-webhook
sudo systemctl enable gitee-webhook

检查服务状态:

sudo systemctl status gitee-webhook

没问题的话就可以看到:

Image 3

四、配置服务器防火墙

确保你的云服务器的防火墙和云服务商的安全组都允许 5000 端口的入站连接

五、在 Gitee 仓库中配置 WebHook

Image 4

六、测试

  1. 在本地修改代码并 git push 到 Gitee 仓库。
  2. 检查 Gitee WebHook 状态: 在 Gitee 3. WebHooks 页面查看请求历史,确认状态为“成功”。
  3. 检查服务器日志
sudo journalctl -u gitee-webhook -f