Руководство по интеграции внешнего контекста¶
Руководство по связыванию сущностей кода CPG с внешними системами (Git, Issue Trackers, APM).
Содержание¶
- Обзор
- Архитектура
- Быстрая настройка
- Интеграция с Git
- GitSyncService
- Доступные теги
- SQL-запросы
- Интеграция с Issue Tracker
- IssueSyncService
- Поддерживаемые провайдеры
- Доступные теги
- Интеграция с APM/Sentry
- SentrySyncService
- Доступные теги
- Использование оркестратора
- Python API
- CLI интерфейс
- Примеры запросов
- Справочник API
- Устранение неполадок
Обзор¶
Интеграция внешнего контекста позволяет связывать сущности кода (методы, функции, классы) в Code Property Graph (CPG) с метаданными из внешних систем:
- Git: информация об авторах, история коммитов, частота изменений
- Issue Trackers: Jira, GitHub Issues, GitLab Issues
- APM/Error Tracking: данные об ошибках Sentry, частота, severity
Это позволяет выполнять мощные запросы, такие как: - “Кто написал этот код?” - “Какие задачи связаны с этой функцией?” - “Какие методы вызывают больше всего ошибок в production?” - “Какой код чаще всего изменяется?”
Архитектура¶
┌─────────────────────────────────────────────────────────────┐
│ Внешние системы │
├─────────────┬─────────────────────┬─────────────────────────┤
│ Git │ Issue Trackers │ Sentry │
│ (коммиты) │ (Jira/GitHub/GL) │ (ошибки) │
└──────┬──────┴──────────┬──────────┴────────────┬────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────┐
│ ExternalContextOrchestrator │
│ ┌─────────────┐ ┌───────────────┐ ┌───────────────────┐ │
│ │GitSyncService│ │IssueSyncService│ │SentrySyncService │ │
│ └─────────────┘ └───────────────┘ └───────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────────┐
│ PostgreSQL │ │ ChromaDB │
│ (сырые данные) │ │ (семантический поиск)│
└────────┬─────────┘ └──────────┬───────────┘
│ │
└───────────────────┬───────────────────┘
▼
┌─────────────────┐
│ DuckDB CPG │
│ (nodes_tag) │
└─────────────────┘
Быстрая настройка¶
1. Установка зависимостей¶
pip install -r requirements.txt
2. Настройка переменных окружения¶
# Git (дополнительная настройка не требуется - использует локальный git)
# GitHub Issues
export GITHUB_TOKEN="ghp_xxxxxxxxxxxx"
# GitLab Issues
export GITLAB_TOKEN="glpat-xxxxxxxxxxxx"
# Jira
export JIRA_TOKEN="your_jira_api_token"
export JIRA_EMAIL="your@email.com"
# Sentry
export SENTRY_AUTH_TOKEN="your_sentry_token"
3. Запуск начальной синхронизации¶
from src.services.external_context import ExternalContextOrchestrator
# Инициализация оркестратора
orchestrator = ExternalContextOrchestrator(
duckdb_conn=your_duckdb_connection,
pg_conn=your_postgres_connection, # опционально
repo_path="/path/to/your/repo"
)
# Синхронизация всех источников
result = await orchestrator.sync_all(
git_config={"since_days": 90, "include_blame": True},
issue_config={"provider": "github", "repo": "owner/repo", "token": os.getenv("GITHUB_TOKEN")},
sentry_config={"org_slug": "my-org", "project_slug": "my-project", "token": os.getenv("SENTRY_AUTH_TOKEN")}
)
print(result)
Интеграция с Git¶
GitSyncService¶
Синхронизирует метаданные истории git в теги CPG.
from src.services.external_context import GitSyncService
service = GitSyncService(
duckdb_conn=conn,
pg_conn=pg_conn, # опционально, для хранения сырых данных
repo_path="/path/to/repo"
)
# Синхронизация за последние 30 дней
result = await service.sync(since_days=30, include_blame=True)
print(f"Синхронизировано {result.items_synced} коммитов, создано {result.tags_created} тегов")
Доступные Git теги¶
| Имя тега | Описание | Пример значения |
|---|---|---|
git-commit |
SHA последнего коммита, изменившего метод | a1b2c3d4... |
git-author |
Email автора последнего изменения | dev@company.com |
git-branch |
Ветка происхождения кода | feature/PROJ-123 |
git-blame-count |
Количество уникальных авторов | 3 |
git-churn |
Количество изменений | 15 |
git-last-modified |
Время последнего изменения | 2025-01-09T10:30:00Z |
Git запросы¶
-- Найти все методы, измененные конкретным автором
SELECT m.full_name, m.filename, t.value as author
FROM nodes_method m
JOIN edges_tagged_by e ON m.id = e.src
JOIN nodes_tag t ON e.dst = t.id
WHERE t.name = 'git-author' AND t.value = 'developer@example.com';
-- Найти код с высокой частотой изменений (методы, измененные > 10 раз)
SELECT m.full_name, CAST(t.value AS INT) as churn_count
FROM nodes_method m
JOIN edges_tagged_by e ON m.id = e.src
JOIN nodes_tag t ON e.dst = t.id
WHERE t.name = 'git-churn' AND CAST(t.value AS INT) > 10
ORDER BY churn_count DESC;
-- Найти кандидатов на bus factor (методы с одним автором)
SELECT m.full_name, t_author.value as sole_author
FROM nodes_method m
JOIN edges_tagged_by e1 ON m.id = e1.src
JOIN nodes_tag t_blame ON e1.dst = t_blame.id
JOIN edges_tagged_by e2 ON m.id = e2.src
JOIN nodes_tag t_author ON e2.dst = t_author.id
WHERE t_blame.name = 'git-blame-count' AND t_blame.value = '1'
AND t_author.name = 'git-author';
Интеграция с Issue Tracker¶
IssueSyncService¶
Связывает задачи с кодом через ссылки в сообщениях коммитов.
from src.services.external_context import IssueSyncService
# GitHub
service = IssueSyncService(
duckdb_conn=conn,
pg_conn=pg_conn,
provider="github",
repo="owner/repo",
token=os.getenv("GITHUB_TOKEN")
)
# Jira
service = IssueSyncService(
duckdb_conn=conn,
pg_conn=pg_conn,
provider="jira",
repo="PROJ", # ключ проекта Jira
token=os.getenv("JIRA_TOKEN"),
base_url="https://company.atlassian.net",
email=os.getenv("JIRA_EMAIL")
)
result = await service.sync()
Поддерживаемые провайдеры¶
| Провайдер | Конфигурация | Паттерн задачи |
|---|---|---|
| GitHub | provider="github" |
#123, GH-123 |
| GitLab | provider="gitlab" |
#123, !123 (MR) |
| Jira | provider="jira" |
PROJ-123 |
Доступные Issue теги¶
| Имя тега | Описание | Пример значения |
|---|---|---|
issue-id |
Идентификатор задачи | PROJ-123, #456 |
issue-type |
Тип задачи | bug, feature, refactor |
issue-status |
Текущий статус | open, closed, in_progress |
issue-label |
Метки задачи | critical, tech-debt |
Интеграция с APM/Sentry¶
SentrySyncService¶
Синхронизирует данные об ошибках из Sentry для выявления проблемного кода.
from src.services.external_context import SentrySyncService
service = SentrySyncService(
duckdb_conn=conn,
pg_conn=pg_conn,
org_slug="my-organization",
project_slug="my-project",
token=os.getenv("SENTRY_AUTH_TOKEN")
)
result = await service.sync(days_back=30)
Доступные Sentry теги¶
| Имя тега | Описание | Пример значения |
|---|---|---|
sentry-issue |
ID ошибки в Sentry | SENTRY-12345 |
error-frequency |
Количество ошибок в день | 150 |
error-level |
Уровень severity | error, fatal, warning |
error-type |
Тип исключения | NullPointerException |
Использование оркестратора¶
Python API¶
from src.services.external_context import ExternalContextOrchestrator
orchestrator = ExternalContextOrchestrator(
duckdb_conn=conn,
pg_conn=pg_conn,
repo_path="."
)
# Синхронизация всех источников
result = await orchestrator.sync_all(
git_config={"since_days": 30, "include_blame": True},
issue_config={"provider": "github", "repo": "owner/repo", "token": token},
sentry_config={"org_slug": "org", "project_slug": "proj", "token": sentry_token},
parallel=True # Запуск синхронизаций параллельно
)
# Синхронизация отдельных источников
git_result = await orchestrator.sync_git(since_days=30)
issue_result = await orchestrator.sync_issues(provider="github", repo="owner/repo", token=token)
sentry_result = await orchestrator.sync_sentry(org_slug="org", project_slug="proj", token=token)
CLI интерфейс¶
# Синхронизация истории git
python -m src.services.external_context.orchestrator \
--repo-path /path/to/repo \
--git --git-days 30 --git-blame
# Синхронизация GitHub issues
python -m src.services.external_context.orchestrator \
--repo-path /path/to/repo \
--issues --issue-provider github --issue-repo owner/repo
# Синхронизация ошибок Sentry
python -m src.services.external_context.orchestrator \
--repo-path /path/to/repo \
--sentry --sentry-org my-org --sentry-project my-project
# Синхронизация всех источников
python -m src.services.external_context.orchestrator \
--repo-path /path/to/repo \
--all --parallel
Примеры запросов¶
Использование CPGQueryService¶
from src.services.cpg_query_service import CPGQueryService
cpg = CPGQueryService(duckdb_conn)
# Найти методы по автору
methods = cpg.get_methods_by_author("developer@example.com", limit=50)
# Получить список всех контрибьюторов
authors = cpg.get_git_authors(limit=20)
# Найти методы, связанные с задачей
methods = cpg.get_methods_by_issue("PROJ-123")
# Найти методы с частыми ошибками
errors = cpg.get_error_prone_methods(min_frequency=10)
# Найти код с высокой частотой изменений
hotspots = cpg.get_git_hotspots(min_churn=5)
# Найти рискованный код по автору (security-risk + author)
risky = cpg.get_risky_code_by_author("developer@example.com")
# Найти кандидатов на bus factor
bus_factor = cpg.get_bus_factor_candidates(max_authors=1)
# Получить статистику внешнего контекста
stats = cpg.get_external_context_stats()
Запросы на естественном языке¶
Workflow onboarding поддерживает запросы на естественном языке для внешнего контекста:
- English: “Who wrote the authentication module?”, “What issues are linked to the parser?”, “Which methods have production errors?”
- Русский: “Кто написал модуль аутентификации?”, “Какие задачи связаны с парсером?”, “Какие методы вызывают ошибки?”
Справочник API¶
Методы CPGQueryService¶
| Метод | Описание | Параметры |
|---|---|---|
get_methods_by_author(email, limit) |
Найти методы по автору | email: str, limit: int |
get_git_authors(limit) |
Список контрибьюторов | limit: int |
get_methods_by_issue(issue_id, limit) |
Найти методы по задаче | issue_id: str, limit: int |
get_error_prone_methods(min_frequency, limit) |
Найти проблемные методы | min_frequency: int, limit: int |
get_git_hotspots(min_churn, limit) |
Найти часто изменяемый код | min_churn: int, limit: int |
get_risky_code_by_author(email, limit) |
Автор + security risk | email: str, limit: int |
get_bus_factor_candidates(max_authors, limit) |
Код с одним владельцем | max_authors: int, limit: int |
get_external_context_stats() |
Статистика тегов | - |
Методы HybridExternalSearch¶
| Метод | Описание |
|---|---|
find_methods_by_author(email) |
Гибридный поиск кода автора |
find_methods_by_issue(issue_id) |
Гибридный поиск кода по задаче |
find_error_prone_methods() |
Гибридный поиск проблемного кода |
find_code_for_incident(description) |
Семантический поиск по описанию инцидента |
Устранение неполадок¶
Теги не создаются¶
- Проверьте, что в базе CPG есть методы в
nodes_method - Убедитесь, что пути файлов в CPG соответствуют структуре репозитория
- Запустите синхронизацию с
include_blame=Trueдля git
Rate Limiting GitHub¶
# Используйте аутентифицированные запросы
service = IssueSyncService(
provider="github",
token=os.getenv("GITHUB_TOKEN") # Требуется для более высоких лимитов
)
Ошибки API Sentry¶
- Проверьте правильность
org_slugиproject_slug - Убедитесь, что токен имеет права
project:readиevent:read - Попробуйте с
--sentry-days 7для меньшего объема данных
Дальнейшие шаги¶
- SQL Query Cookbook - Дополнительные примеры SQL
- Сценарий Onboarding - Использование внешнего контекста в запросах
- Архитектура - Детали архитектуры системы