GitHub Integration — Гайд по настройке
Phase 49.3 (Light) — webhook-уведомления + UI sidebar feed для подключённых GitHub-репозиториев. Без bidirectional sync (это Phase 49.5+ Heavy).
Arc OS принимает webhook-события из подключённых GitHub-репозиториев и одновременно:
- Отправляет Telegram-уведомление владельцу проєкта
- Обновляет sidebar feed в Workspace ContextRail (поллинг 30 сек)
Архитектура
GitHub repo
│ (push / PR / CI / issue events)
▼
arc-os.co/api/webhooks/github
│ HMAC-SHA256 timing-safe verify (X-Hub-Signature-256)
│ Rate limit 100 req/min/project
│ Payload max 50KB
▼
shared/routes/github.ts handleGithubWebhook
├─→ DB: github_events (для UI feed)
└─→ shared/github-notifier.ts → Telegram (master bot token)
Поддерживаемые события: push, pull_request, workflow_run, issues. Остальные (releases, deployments, discussions) игнорируются.
Multi-repo: один проект может подключить несколько репозиториев (например, frontend + backend + docs). Ограничение: UNIQUE(project_name, owner, repo).
Быстрая настройка (3 минуты)
1. Сгенерируй webhook URL + secret
arc github link <project-name> <owner/repo>
Пример:
arc github link arc-v2 SerhiiInUa/citadel-v2
CLI вернёт:
- Webhook URL —
https://arc-os.co/api/webhooks/github - Secret — 32-байтный hex (уникальный для каждого подключения)
- Пошаговые инструкции для GitHub UI
2. Добавь webhook в GitHub-репозиторий
На странице https://github.com/<owner>/<repo>/settings/hooks:
- Нажми Add webhook
- Payload URL:
https://arc-os.co/api/webhooks/github - Content type:
application/json(важно!) - Secret: вставь значение из вывода CLI
- Which events? → «Let me select individual events»:
- ☑ Pushes
- ☑ Pull requests
- ☑ Workflow runs
- ☑ Issues
- ☑ Active
- Нажми Add webhook
GitHub сразу отправит тестовый ping-ивент — он будет молча отклонён (Arc ожидает только поддерживаемые типы). Это нормально.
3. Проверь, что всё работает
Сделай push в репозиторий, или открой PR, или запусти workflow. Через ~1-3 секунды:
- Придёт Telegram-уведомление владельцу проекта с иконкой + кратким описанием + ссылкой на GitHub
- Sidebar feed в Workspace ContextRail обновится (через ~30 сек поллинга)
Управление подключениями
Список подключённых репозиториев
arc github links arc-v2
Удалить подключение
arc github unlink arc-v2 <id>
ID берётся из вывода arc github links. Webhook в GitHub при этом не удаляется автоматически — невалидные подписи будут молча отклоняться. Лучший воркфлоу: сначала удали webhook в GitHub UI, затем arc github unlink.
Безопасность
- HMAC-SHA256 подпись — каждый webhook secret =
crypto.randomBytes(32).toString('hex')(256 бит энтропии) - Timing-safe сравнение —
node:crypto timingSafeEqualпредотвращает timing-атаки на верификацию подписи - Молчаливый отказ — невалидные подписи получают
401 ""без тела (не раскрывает информацию сканерам) - Rate limit — 100 req/min на проект (in-memory окно). Превышение →
429 Rate limited - Ограничение размера payload — 50 КБ в хендлере, 64 КБ в nginx (защита от DoS)
- Маршрутизация подписи multi-repo — хендлер ищет кандидатов по
repository.full_name, затем проверяет подпись каждого перед принятием (предотвращает повторное использование secret между проектами) - Изоляция публичного эндпоинта — nginx-конфиг
/api/webhooks/githubимеетauth_basic offиproxy_read_timeout 5s
Что видно в sidebar
ContextRail (правая панель в Workspace) показывает секцию GitHub ⤵
- Автоматически скрывается, если у проекта нет подключённых репозиториев
- Последние 8 событий (новые первые)
- Иконка для каждого события: GitBranch (push) / GitPullRequest (PR) / CircleCheck (CI success) / CircleAlert (CI failure) / CircleDot (issues)
- Относительный формат времени: 30s, 5m, 2h, 1d
- Клик по строке → открывает GitHub URL в новой вкладке
- Поллинг каждые 30 сек (свежие данные без ручного обновления)
Telegram-уведомления
Master Bot отправляет форматированное сообщение владельцу проекта:
🔀 [arc-v2] SerhiiInUa/citadel-v2
PR #42 opened: feat: add lazy worker lifecycle by @Sergei89
View on GitHub
Иконки:
- 📦 push
- 🔀 pull_request
- ✅ workflow_run (success)
- ❌ workflow_run (failure)
- ⚙️ workflow_run (other)
- 🐛 issues
Устранение неполадок
Webhook возвращает 401 на тестовый ping
Ожидаемо — Arc молча отклоняет неподдерживаемые события (например, ping). Обрабатываются только production-события (push, PR, workflow_run, issues).
Webhook возвращает 401 на push-ивент
- Убедись, что в настройках webhook GitHub выбран
Content type: application/json(неform-urlencoded) - Проверь secret — должен точно совпадать с тем, что вернул
arc github link - Если secret утерян — удали подключение и создай заново (
arc github unlink→arc github link)
Sidebar feed пустой, хотя Telegram-уведомления приходят
- Убедись, что ContextRail вообще виден (viewport ≥1280px)
- Жёсткое обновление страницы (Ctrl+Shift+R) — компонент кешируется
- Проверь БД:
sqlite3 data/citadel.db "SELECT COUNT(*) FROM github_events WHERE project_name='<name>';"
Telegram-уведомления не приходят
- Убедись, что у проекта есть
owner_idв БД:sqlite3 ... "SELECT name, owner_id FROM projects;" - Проверь токен master bot в vault:
grep MASTER_BOT_TOKEN config/vault.json(должен быть зашифрован) - Ивент есть в БД, но уведомление не отправлено → смотри логи master:
tmux capture-pane -t citadel-master -p | grep github-notifier
Превышен rate limit
Жёсткий лимит 100 req/min/project. При CI с тысячами runner-ов — повысь в shared/routes/github.ts:RATE_MAX.
API эндпоинты
Подробно: API Reference.
| Эндпоинт | Auth | Описание |
|---|---|---|
POST /api/crm/projects/:name/github |
JWT | Подключить репозиторий |
GET /api/crm/projects/:name/github |
JWT | Список подключений |
DELETE /api/crm/projects/:name/github/:id |
JWT | Отключить |
GET /api/crm/projects/:name/github/events?limit=N |
JWT | Список событий (макс. 200) |
POST /api/webhooks/github |
HMAC | Публичный приёмник |
Roadmap
| Фаза | Скоуп | Статус |
|---|---|---|
| 49.3 | Webhook-приёмник + Telegram | ✅ DONE |
| 49.3.1 | UI sidebar feed | ✅ DONE |
| 49.4 | API поллинг, вкладка GitHub в Workspace, multi-repo дашборд | BACKLOG (P2) |
| 49.5 | Двунаправленная синхронизация задач, авто-ревью PR воркерами | BACKLOG (P2) |