Автоматический code review для GitHub Pull Requests с использованием Claude AI.
📚 Документация и гайды | 🚀 Миграция на async | 🧠 Claude 4.5 Sonnet | 🔧 Troubleshooting
- ✅ Автоматический анализ кода при создании/обновлении PR
- 🎯 Ручной review по команде
@MergeBlocker reviewв комментарии - 💬 Интерактивный диалог - отвечайте на комментарии бота и задавайте вопросы
- 📋 Читает AGENTS.md из репозитория для учета project guidelines
- 💬 Inline комментарии к конкретным строкам кода (без ограничений по количеству)
- 📝 Структурированные reviews с summary, критическими проблемами и рекомендациями
- 🔄 JSON формат с автоматическими retry при ошибках парсинга
- 🎨 Красивые GitHub Check Runs для визуального статуса
- 🧠 Детальный анализ: всегда генерирует inline комментарии к коду
- 🔒 Безопасность: проверка webhook signature (HMAC SHA-256)
- 🧪 Автотесты: unit и integration тесты с pytest
- 🚀 CI/CD: автоматический lint, test, build и deploy через GitHub Actions
- Python 3.11+
- Poetry (для dependency management) или pip
- GitHub App с правами:
- Pull requests: Read & Write (reviews и inline comments)
- Issues: Read & Write (чтение команд в комментариях)
- Contents: Read-only (чтение AGENTS.md и файлов)
- Checks: Read & Write (статусы Check Runs)
- Metadata: Read-only (автоматически)
- LLM API key (OpenRouter-compatible API):
- Model:
eliza-Internal-DeepSeek-V3-1-Terminus - Same setup as ML-API project
- Model:
cd /path/to/merge-blokerpython -m venv venv
source venv/bin/activate # На Windows: venv\Scripts\activate
pip install -r requirements.txtВаше приложение: https://github.com/settings/apps/mergeblocker
В разделе Permissions & events:
- Repository permissions:
- Pull requests:
Read & write(для создания reviews и inline comments) - Issues:
Read & write(для чтения команд@MergeBlocker review) - Contents:
Read-only(для чтенияAGENTS.mdи файлов PR) - Checks:
Read & write(для Check Runs статусов) - Commit statuses:
Read & write(опционально) - Metadata:
Read-only(автоматически)
- Pull requests:
В разделе Subscribe to events:
- ✅ Pull request (для автоматического review)
- ✅ Issue comment (для команды
@MergeBlocker review) - ✅ Pull request review comment (для ответов на комментарии бота)
📖 Подробнее о настройке reply функциональности: docs/SETUP_REPLY_FUNCTIONALITY.md
- Прокрутите до раздела Private keys
- Нажмите Generate a private key
- Скачайте
.pemфайл - Переместите его в корень проекта:
private-key.pem
private-key.pem в git!
В разделе General → Webhook:
- Webhook URL:
https://your-domain.com/webhook- Для разработки используйте ngrok или smee.io (см. ниже)
- Secret: сгенерируйте случайный секрет (например:
openssl rand -hex 32) - Active: ✅ включите
Скопируйте .env.example в .env:
cp .env.example .envОтредактируйте .env:
GITHUB_APP_ID=2469635
GITHUB_PRIVATE_KEY_PATH=./private-key.pem
GITHUB_WEBHOOK_SECRET=your_webhook_secret_here
ANTHROPIC_API_KEY=your_anthropic_api_key_here
PORT=8000
HOST=0.0.0.0
DEBUG=False- Перейдите: https://github.com/settings/apps/mergeblocker/installations
- Нажмите Install или Configure
- Выберите репозитории (или все)
python app.pyСервер запустится на http://0.0.0.0:8002
GitHub требует публичный HTTPS endpoint для webhooks. Варианты:
# Установите ngrok: https://ngrok.com/download
ngrok http 8002Вы получите URL типа https://abc123.ngrok.io
Укажите в GitHub App Webhook URL: https://abc123.ngrok.io/webhook
npm install -g smee-client
# Создайте channel на https://smee.io
smee --url https://smee.io/abc123 --path /webhook --port 8002Укажите в GitHub App Webhook URL: https://smee.io/abc123
- Создайте или обновите Pull Request
- GitHub отправит webhook (
pull_requestevent) - Приложение автоматически:
- Читает
AGENTS.md(если есть в репозитории) - Проанализирует изменения
- Запустит AI review с учетом project guidelines
- Оставит summary comment в Conversation
- Добавит inline комментарии в Files Changed (до 10 штук)
- Обновит Check Run статус
- Читает
Напишите комментарий в PR:
@MergeBlocker review
Бот автоматически:
- Получит webhook (
issue_commentevent) - Запустит полный анализ PR
- Оставит review с учетом
AGENTS.md
Когда использовать:
- ✅ Для повторного анализа после изменений
- ✅ Если автоматический review не сработал
- ✅ Для запуска review в старом PR
После того как бот оставил комментарий к коду:
- Найдите inline комментарий бота в Files Changed
- Нажмите Reply под комментарием
- Задайте вопрос (например: "Почему это плохо?", "Как правильно исправить?")
- Бот автоматически ответит с учетом контекста кода и PR
Примеры вопросов:
- "Можешь показать пример исправления?"
- "Почему это может привести к багу?"
- "Есть ли альтернативные подходы?"
- "Это критическая проблема?"
📖 Требует настройки: docs/SETUP_REPLY_FUNCTIONALITY.md
Настройки в .env:
| Параметр | Описание | По умолчанию |
|---|---|---|
SKIP_DRAFT_PRS |
Пропускать draft PR | True |
┌─────────────────────────────────────────────────────────────────────────┐
│ GitHub Pull Request │
│ │
│ 1. PR создан/обновлен OR 2. Комментарий "@MergeBlocker review" │
└──────────────────────────────┬──────────────────────────────────────────┘
│ Webhook (POST /webhook)
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Flask Server (app.py) │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ 1. Verify webhook signature (HMAC SHA-256) │ │
│ │ 2. Parse event (pull_request или issue_comment) │ │
│ │ 3. Check event type (opened/synchronized или command) │ │
│ └────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────┬──────────────────────────────────────────┘
│ process_pr_review(pr_info)
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Step 1: Create Check Run │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ GitHub Client → create_check_run() │ │
│ │ Status: "in_progress" ⏳ │ │
│ │ Title: "Analyzing code changes..." │ │
│ └────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────┬──────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Step 2: Fetch PR Context │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ GitHub Client → get_pr_context() │ │
│ │ • PR metadata (title, body, author, labels) │ │
│ │ • Changed files (filename, status, additions, deletions) │ │
│ │ • Patches (diffs for each file) │ │
│ │ • Commits (last 5 for context) │ │
│ │ • Statistics (total files, lines changed) │ │
│ └────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────┬──────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Step 2.5: Read AGENTS.md (if exists) 📋 │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ GitHub Client → get_file_content("AGENTS.md") │ │
│ │ • Читает guidelines из репозитория │ │
│ │ • Используется в промптах для LLM │ │
│ │ • Позволяет учитывать правила проекта │ │
│ └────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────┬──────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Step 3: Quick Deterministic Checks ⚡ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ Code Analyzer → quick_check() │ │
│ │ • Поиск потенциальных секретов (api_key, password, token) │ │
│ │ • Поиск TODO/FIXME комментариев │ │
│ │ • Проверка размера PR │ │
│ │ • Immediate warnings (без LLM) │ │
│ └────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────┬──────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Step 4: AI Analysis 🧠 │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ Code Analyzer → analyze_pr(pr_context, agents_md_content) │ │
│ │ │ │
│ │ Всегда делается детальный анализ: │ │
│ │ • Полный анализ всех изменений (без ограничений) │ │
│ │ • Inline комментарии к конкретным строкам (без ограничений) │ │
│ │ • Структурированный JSON: summary, critical_issues, │ │
│ │ suggestions, inline_comments │ │
│ │ • Автоматический retry при невалидном JSON (до 3 попыток) │ │
│ │ │ │
│ │ LLM Client (OpenRouter API): │ │
│ │ • Model: eliza-Internal-DeepSeek-V3-1-Terminus │ │
│ │ • System Prompt: Expert code reviewer роль │ │
│ │ • User Prompt: PR context + AGENTS.md + changed files │ │
│ │ │ │
│ │ Анализирует: │ │
│ │ • Security issues (secrets, vulnerabilities) │ │
│ │ • Potential bugs and edge cases │ │
│ │ • Code quality and maintainability │ │
│ │ • Performance concerns │ │
│ │ • Best practices for language/framework │ │
│ │ • Testing coverage │ │
│ │ • Соответствие AGENTS.md guidelines │ │
│ │ │ │
│ │ Возвращает: │ │
│ │ { │ │
│ │ "summary": "Overview + Critical Issues + Suggestions", │ │
│ │ "inline_comments": [ │ │
│ │ {"path": "file.py", "line": 42, "body": "comment"}, │ │
│ │ ... │ │
│ │ ] │ │
│ │ } │ │
│ └────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────┬──────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Step 5: Format Review 📝 │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ Review Formatter → format_review_comment() │ │
│ │ │ │
│ │ Создает красивый markdown comment: │ │
│ │ • Header с emoji и metadata │ │
│ │ • Quick warnings (если есть) │ │
│ │ • AI review summary │ │
│ │ • Inline comments notice │ │
│ │ • Footer с disclaimer │ │
│ └────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────┬──────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Step 6: Post Review with Inline Comments 💬 │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ GitHub Client → create_review() │ │
│ │ │ │
│ │ body: formatted review summary │ │
│ │ comments: [ │ │
│ │ { │ │
│ │ path: "src/api.py", │ │
│ │ line: 42, │ │
│ │ body: "🐛 Potential bug: ..." │ │
│ │ }, │ │
│ │ ... │ │
│ │ ] │ │
│ │ event: "COMMENT" │ │
│ │ │ │
│ │ Результат в GitHub: │ │
│ │ ✅ Summary comment в Conversation │ │
│ │ ✅ Inline comments в Files Changed │ │
│ └────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────┬──────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Step 7: Update Check Run ✅ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ GitHub Client → create_check_run() │ │
│ │ Status: "completed" │ │
│ │ Conclusion: "success" │ │
│ │ Title: "✅ Review Completed" │ │
│ │ Summary: Statistics + warnings │ │
│ └────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
-
Автоматический (pull_request event):
- PR открыт (
opened) - PR обновлен (
synchronize) - Пропускаются:
closed, draft PR (еслиSKIP_DRAFT_PRS=True)
- PR открыт (
-
Ручной (issue_comment event):
- Комментарий
@MergeBlocker reviewв PR - Запускает полный анализ независимо от предыдущих reviews
- Комментарий
merge-bloker/
├── app.py # Главный Flask сервер (точка входа)
├── requirements.txt # Python зависимости (pip)
├── pyproject.toml # Poetry конфигурация и метаданные
├── poetry.lock # Locked версии зависимостей
├── .env # Environment variables (создайте из .env.example)
├── .env.example # Пример конфигурации
├── .gitignore # Git ignore
├── private-key.pem # GitHub App private key (не в git!)
│
├── src/ # Исходный код приложения
│ ├── config.py # Конфигурация и environment variables
│ │
│ ├── clients/ # Клиенты для внешних API
│ │ ├── github_client.py # GitHub API (PyGithub)
│ │ └── llm_client.py # LLM API (OpenRouter-compatible)
│ │
│ ├── analysis/ # Анализ кода и форматирование
│ │ ├── code_analyzer.py # Главная логика анализа
│ │ ├── prompts.py # LLM промпты для review
│ │ └── review_formatter.py # Форматирование результатов
│ │
│ └── handlers/ # Обработчики событий
│ └── webhook_handler.py # Парсинг и валидация webhooks
│
├── tests/ # Тесты
│ ├── conftest.py # Pytest fixtures
│ ├── test_webhook_handler.py # Unit тесты WebhookHandler
│ ├── test_llm_integration.py # Integration тесты LLM
│ └── README.md # Документация по тестам
│
├── .github/ # GitHub Actions CI/CD
│ └── workflows/
│ ├── deploy.yaml # Build & Deploy workflow
│ └── test.yaml # Lint & Test workflow
│
├── Dockerfile # Docker образ для production
├── docker-compose.yaml # Docker Compose для разработки
├── docker-compose.prod.yaml # Docker Compose для production
├── .dockerignore # Игнорируемые файлы для Docker
│
├── deploy.sh # Скрипт деплоя на сервер
├── generate-env.sh # Генерация .env из переменных окружения
├── start-local.sh # Скрипт для локального запуска
│
├── .flake8 # Конфигурация flake8 linter
├── README.md # Основная документация (вы здесь!)
│
└── docs/ # Дополнительная документация
├── DEPLOYMENT.md # CI/CD и деплой
├── SETUP_GUIDE.md # Детальная инструкция по настройке
├── QUICK_START.md # Быстрый старт (5 минут)
├── ARCHITECTURE.md # Архитектура системы
├── PROJECT_SUMMARY.md # Сводка проекта
└── NEXT_STEPS.md # Следующие шаги после установки
Логи выводятся в stdout. Уровень логирования: INFO.
Для debug режима установите в .env:
DEBUG=TrueОтправьте тестовый webhook из GitHub:
- Перейдите: Settings → Apps → MergeBlocker → Advanced
- Найдите раздел "Recent Deliveries"
- Нажмите "Redeliver" на любом событии
- Создайте тестовый PR в репозитории
- Проверьте логи сервера
- Через ~30-60 секунд должен появиться комментарий
Проект настроен для автоматического деплоя через GitHub Actions:
-
Push в master → автоматически:
- Собирается Docker образ
- Пушится в GitHub Container Registry
- Деплоится на сервер через SSH
-
Настройка: см. docs/DEPLOYMENT.md
# Development
docker compose up
# Production
docker compose -f docker-compose.prod.yaml up -d# На сервере
git clone git@github.com:TimurQQ/MergeBlocker.git
cd MergeBlocker
# Настройте .env и private-key.pem
cp .env.example .env
# Отредактируйте .env
# Запустите деплой
./deploy.sh- CI/CD: Используйте GitHub Actions (уже настроено)
- Мониторинг: Sentry для ошибок, Prometheus для метрик
- Reverse Proxy: Nginx с SSL/TLS
- Task Queue: Celery + Redis для асинхронной обработки
- База данных: PostgreSQL для истории reviews
- Кэширование: Redis для токенов и результатов
Подробнее: docs/DEPLOYMENT.md
- Проверьте, что Webhook Active ✅
- Проверьте Recent Deliveries в GitHub (Settings → Apps → Advanced)
- Убедитесь, что endpoint доступен публично (попробуйте
curl https://your-url/) - Проверьте логи сервера
- Проверьте
GITHUB_WEBHOOK_SECRETв.env - Убедитесь, что secret совпадает с GitHub App
- Убедитесь, что
private-key.pemсуществует - Проверьте путь в
GITHUB_PRIVATE_KEY_PATH
- Проверьте логи сервера
- Убедитесь, что PR не в draft (если
SKIP_DRAFT_PRS=True) - Проверьте, что у App есть права Pull requests: Read & Write
- Убедитесь, что App установлен в репозиторий
- Проверьте
ANTHROPIC_API_KEY - Убедитесь, что у вас есть доступ к Claude API
- Проверьте квоты и лимиты
Для всех PR (независимо от размера):
- ✅ Полный детальный анализ всех изменений (без ограничений по количеству файлов)
- ✅ Inline комментарии к конкретным строкам кода (без ограничений по количеству)
- ✅ Структурированный JSON response с retry механизмом
- ✅ Summary (общая оценка PR)
- ✅ Critical Issues (критические проблемы безопасности/баги)
- ✅ Suggestions (рекомендации по улучшению)
- ✅ Учет guidelines из AGENTS.md (если есть в репозитории)
Примечание:
- LLM возвращает структурированный JSON, при ошибках парсинга автоматически retry (до 3 попыток)
Быстрые проверки:
- Потенциальные секреты (api_key, password, etc.)
- TODO/FIXME в новом коде
- Размер PR
AI анализ:
- Security issues
- Потенциальные баги
- Edge cases
- Code quality
- Best practices
- Performance concerns
- Testing coverage
Pull requests приветствуются! Для крупных изменений сначала откройте issue.
MIT
Вопросы? Создайте issue в репозитории!