Интеграция AI в пайплайны GitHub Actions: авто-ревью кода через Claude API, генерация описаний PR, умные тесты и автоматическая документация.
Создаём workflow-файл в .github/workflows/. Используем pull_request_target для доступа к секретам (нужен для API-ключей). Фильтруем по путям — AI-анализ запускается только при изменении кода в src/ и tests/. Настраиваем права GITHUB_TOKEN.
# .github/workflows/ai-review.yml name: AI Code Review & Smart CI on: pull_request_target: types: [opened, synchronize, reopened] paths: - 'src/**' - 'tests/**' - '*.py' - '*.ts' permissions: contents: read pull-requests: write issues: write jobs: ai-review: runs-on: ubuntu-latest timeout-minutes: 10 env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} steps: - uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0
В следующем шаге получаем git diff между базовой веткой и PR. Передаём его Claude с промптом на ревью. Модель анализирует изменения и возвращает структурированный отчёт с замечаниями, предложениями и оценкой безопасности.
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: pip install anthropic PyGithub
- name: AI Code Review
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
BASE_REF: ${{ github.event.pull_request.base.sha }}
run: python scripts/ai_review.py
Сам скрипт ai_review.py получает diff, отправляет Claude, парсит ответ и публикует комментарии прямо в PR через GitHub API. Для каждого найденного замечания создаётся отдельный thread с указанием файла и строки.
# scripts/ai_review.py import os, json, subprocess from anthropic import Anthropic from github import Github # Получаем diff между базовой веткой и PR diff = subprocess.run( ["git", "diff", os.environ["BASE_REF"]], capture_output=True, text=True ).stdout # Если diff слишком большой — обрезаем до первых 15000 символов if len(diff) > 15000: diff = diff[:15000] + "\n... (обрезано)" # Отправляем Claude на ревью client = Anthropic() response = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=2048, system="Ты — senior code reviewer. Найди баги, уязвимости, " "нарушения best practices. Ответь JSON-массивом замечаний.", messages=[{ "role": "user", "content": f"Проревьюируй этот diff:\n{diff}" }] ) # Парсим ответ и публикуем комментарии в PR review_data = json.loads(response.content[0].text) gh = Github(os.environ["GITHUB_TOKEN"]) repo = gh.get_repo(os.environ["GITHUB_REPOSITORY"]) pr = repo.get_pull(int(os.environ["PR_NUMBER"])) for item in review_data: pr.create_issue_comment( f"🤖 **AI Review:** {item['severity']} — {item['message']}\n" f"📁 `{item.get('file', 'N/A')}:{item.get('line', '?')}`\n" f"💡 {item.get('suggestion', '')}" ) print(f"✅ Опубликовано {len(review_data)} замечаний")
Второй job в workflow — генерация читаемого описания PR. Анализируем список изменённых файлов и сообщения коммитов, отправляем Claude и обновляем тело PR через API. Это экономит разработчикам время на документирование изменений.
# scripts/generate_pr_description.py import os, subprocess, json from anthropic import Anthropic from github import Github # Собираем контекст: изменённые файлы + коммиты files_changed = subprocess.run( ["git", "diff", "--name-only", os.environ["BASE_REF"]], capture_output=True, text=True ).stdout commits = subprocess.run( ["git", "log", "--oneline", f"{os.environ['BASE_REF']}..HEAD"], capture_output=True, text=True ).stdout client = Anthropic() response = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=1024, system="Сгенерируй описание Pull Request на русском. Формат: заголовок, описание, список изменений, как тестировать.", messages=[{"role": "user", "content": f"Изменённые файлы:\n{files_changed}\n\nКоммиты:\n{commits}" }] ) description = response.content[0].text gh = Github(os.environ["GITHUB_TOKEN"]) repo = gh.get_repo(os.environ["GITHUB_REPOSITORY"]) pr = repo.get_pull(int(os.environ["PR_NUMBER"])) current_body = pr.body or "" pr.edit(body=f"{current_body}\n\n---\n🤖 **AI-Generated Summary:**\n{description}") print("✅ PR описание обновлено")
AI анализирует изменённый код и автоматически генерирует релевантные тесты. Система определяет, какие функции изменились, и создаёт юнит-тесты с граничными случаями. Результат добавляется комментарием в PR для ручного ревью перед мержем.
# scripts/generate_tests.py import os, subprocess, re from anthropic import Anthropic from github import Github # Получаем все изменённые .py файлы changed_files = subprocess.run( ["git", "diff", "--name-only", os.environ["BASE_REF"], "--", "*.py"], capture_output=True, text=True ).stdout.strip().split("\n") client = Anthropic() all_tests = [] for filepath in changed_files: if not filepath or "test_" in filepath: continue with open(filepath) as f: source = f.read() response = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=2048, system="Сгенерируй pytest-тесты для этого кода. Включи граничные случаи и mock-объекты. Выведи только код.", messages=[{"role": "user", "content": source}] ) test_code = response.content[0].text all_tests.append(f"### 🧪 Tests for `{filepath}`\n```python\n{test_code}\n```") # Публикуем в PR gh = Github(os.environ["GITHUB_TOKEN"]) repo = gh.get_repo(os.environ["GITHUB_REPOSITORY"]) pr = repo.get_pull(int(os.environ["PR_NUMBER"])) pr.create_issue_comment("## 🤖 AI-Generated Tests\n\n" + "\n\n".join(all_tests))
Интеграция AI в GitHub Actions превращает пайплайн из пассивного исполнителя в активного участника разработки. Автоматическое ревью ловит баги до того, как их заметят люди. Генерация описаний PR и тестов экономит часы рутинной работы. Ключевое преимущество — agent работает асинхронно и не блокирует разработчика. Достаточно добавить API-ключ в Secrets репозитория и workflow-файл в .github/workflows.