一、准备服务器环境
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
|
输入:
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')
REPO_PATH = "/var/www/your-project"
WEBHOOK_SECRET = "YOUR_GITEE_WEBHOOK_SECRET"
@app.route('/webhook', methods=['POST']) def webhook(): logging.info("Received a webhook request.")
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.")
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}")
try: os.chdir(REPO_PATH) logging.info(f"Executing git reset --hard origin/main and git pull in {REPO_PATH}...")
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}")
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
|
没问题的话就可以看到:
四、配置服务器防火墙
确保你的云服务器的防火墙和云服务商的安全组都允许 5000 端口的入站连接
五、在 Gitee 仓库中配置 WebHook
六、测试
- 在本地修改代码并 git push 到 Gitee 仓库。
- 检查 Gitee WebHook 状态: 在 Gitee 3. WebHooks 页面查看请求历史,确认状态为“成功”。
- 检查服务器日志
sudo journalctl -u gitee-webhook -f
|
七、后话:两个月之后,被gitee封ip了
真无语了,要不是服务器在国内,谁用你gitee
换ssh连接了,但不知道后续还会不会被封
SSH 密钥配置流程:
1、停止 Webhook 服务
sudo systemctl stop gitee-webhook.service
|
2、确保运行 Webhook 服务的用户 (例如 www-data
) 对 REPO_PATH 目录有读写权限
sudo chown -R www-data:www-data /var/www/your-project-directory sudo find /var/www/your-project-directory -type d -exec chmod 755 {} \; sudo find /var/www/your-project-directory -type f -exec chmod 644 {} \;
|
3、以运行 Webhook 的用户身份生成 SSH 密钥对:
sudo mkdir -p /var/www/your-project-directory/.ssh sudo chown www-data:www-data /var/www/your-project-directory/.ssh sudo chmod 700 /var/www/your-project-directory/.ssh sudo -u www-data ssh-keygen -t rsa -b 4096 -C "your_email@example.com" -f /var/www/your-project-directory/.ssh/id_rsa
|
4、复制生成的公钥内容
sudo -u www-data cat /var/www/your-project-directory/.ssh/id_rsa.pub
|
5、登录 Gitee,进入你的仓库设置 -> WebHooks -> SSH 公钥,将复制的公钥粘贴并添加
6、确保你的 Git 仓库的远程 URL 已设置为 SSH 格式
cd /var/www/your-project-directory sudo -u www-data git remote set-url origin git@gitee.com:your_username/your_repo.git
|
7、测试 SSH 连接 (以 www-data 用户身份)
sudo -u www-data ssh -T git@gitee.com -i /var/www/your-project-directory/.ssh/id_rsa
|
8、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')
REPO_PATH = "/var/www/your-project"
WEBHOOK_SECRET = "YOUR_GITEE_WEBHOOK_SECRET"
SSH_KEY_PATH = os.path.join(REPO_PATH, ".ssh", "id_rsa")
@app.route('/webhook', methods=['POST']) def webhook(): logging.info("Received a webhook request.")
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.")
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}")
try: os.chdir(REPO_PATH) logging.info(f"Executing git fetch origin and git reset --hard origin/main in {REPO_PATH} using SSH...")
env = os.environ.copy() env["GIT_SSH_COMMAND"] = f"ssh -i {SSH_KEY_PATH} -o StrictHostKeyChecking=no"
result_fetch = subprocess.run( ['git', 'fetch', 'origin'], capture_output=True, text=True, check=True, env=env ) logging.info(f"Git fetch successful: {result_fetch.stdout}") if result_fetch.stderr: logging.warning(f"Git fetch had stderr output: {result_fetch.stderr}")
result_reset = subprocess.run( ['git', 'reset', '--hard', 'origin/main'], capture_output=True, text=True, check=True, env=env ) 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}")
return jsonify({"message": "Git fetch and reset successful", "output": result_reset.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
|
9、重启服务
sudo systemctl restart gitee-webhook.service
|