Python中如何实现Mention-bot for Gitlab

正好公司里有需要,网上没找到合适的实现,自己用 Python 轮了一个。

算法照抄 https://github.com/facebook/mention-bot , 部分地方根据 Gitlab 做了适配


Python中如何实现Mention-bot for Gitlab
4 回复

要实现一个GitLab的Mention-bot,核心是监听GitLab的Webhook事件(特别是Merge Request事件),解析评论或描述中的@username,然后通过GitLab API自动添加对应的用户作为Reviewer。

下面是一个使用Flask实现的简单示例。你需要一个可以接收Webhook的公开URL(可以用ngrok在本地测试)。

from flask import Flask, request, jsonify
import requests
import re

app = Flask(__name__)

# 配置你的GitLab私有令牌和项目ID
GITLAB_PRIVATE_TOKEN = 'your_private_token_here'
GITLAB_PROJECT_ID = 'your_project_id_here'
GITLAB_API_BASE = 'https://gitlab.com/api/v4'  # 如果是自托管,换成你的地址

def extract_mentions(text):
    """从文本中提取所有[@username](/user/username)格式的提及"""
    # 匹配 [@username](/user/username) 或 @group/username
    pattern = r'@([a-zA-Z0-9_\-\.]+(?:\/[a-zA-Z0-9_\-\.]+)?)'
    return re.findall(pattern, text)

def get_user_id(username):
    """通过用户名获取GitLab用户ID"""
    url = f"{GITLAB_API_BASE}/users"
    params = {'username': username, 'per_page': 1}
    headers = {'PRIVATE-TOKEN': GITLAB_PRIVATE_TOKEN}
    
    response = requests.get(url, headers=headers, params=params)
    if response.status_code == 200 and response.json():
        return response.json()[0]['id']
    return None

def add_reviewers_to_mr(mr_iid, user_ids):
    """为Merge Request添加Reviewer"""
    url = f"{GITLAB_API_BASE}/projects/{GITLAB_PROJECT_ID}/merge_requests/{mr_iid}"
    headers = {'PRIVATE-TOKEN': GITLAB_PRIVATE_TOKEN}
    data = {'reviewer_ids': user_ids}
    
    response = requests.put(url, headers=headers, json=data)
    return response.status_code == 200

@app.route('/webhook', methods=['POST'])
def handle_webhook():
    event = request.headers.get('X-Gitlab-Event')
    data = request.json
    
    # 只处理Merge Request事件
    if event != 'Merge Request Hook':
        return jsonify({'status': 'ignored'}), 200
    
    # 获取MR信息
    mr_iid = data['object_attributes']['iid']
    description = data['object_attributes'].get('description', '')
    
    # 如果是更新事件,检查最新的评论
    if data.get('object_attributes', {}).get('action') == 'update':
        # 这里简化处理,实际应该检查变更的评论
        pass
    
    # 提取提及的用户名
    mentions = extract_mentions(description)
    if not mentions:
        return jsonify({'status': 'no mentions'}), 200
    
    # 获取用户ID并添加为Reviewer
    user_ids = []
    for username in mentions:
        user_id = get_user_id(username)
        if user_id:
            user_ids.append(user_id)
    
    if user_ids:
        success = add_reviewers_to_mr(mr_iid, user_ids)
        if success:
            return jsonify({'status': 'reviewers added', 'users': user_ids}), 200
    
    return jsonify({'status': 'processed'}), 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

部署步骤:

  1. 安装依赖:pip install flask requests
  2. 替换代码中的your_private_token_hereyour_project_id_here
  3. 在GitLab项目设置中配置Webhook:
    • URL: http://your-server:5000/webhook
    • 触发事件:选择"Merge request events"
  4. 运行这个Flask应用

这个bot会监听MR的创建和更新,当描述中出现@username时,会自动添加该用户为Reviewer。你可以根据需要扩展功能,比如处理评论中的提及,或者添加更复杂的匹配逻辑。

总结:用Webhook监听MR事件,正则提取@mention,调用GitLab API添加reviewer。

尴尬。。。

哈哈,沙发太热情了。

回到顶部