Інтеграція з GitHub — посібник з налаштування
Phase 49.3 (Light) — сповіщення на основі вебхуків + стрічка в сайдбарі UI для прив'язаних GitHub-репозиторіїв. Без двосторонньої синхронізації (це Phase 49.5+ Heavy).
ARC OS отримує події вебхуків від прив'язаних GitHub-репозиторіїв і одночасно:
- Надсилає сповіщення в Telegram власнику проєкту
- Оновлює стрічку в сайдбарі в 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 (for the UI feed)
└─→ shared/github-notifier.ts → Telegram (master bot token)
Підтримувані події: push, pull_request, workflow_run, issues. Решта (releases, deployments, discussions) ігноруються.
Кілька репозиторіїв: один проєкт може прив'язати кілька репозиторіїв (наприклад 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 з іконкою + summary + посиланням на GitHub
- Стрічка в сайдбарі в 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 — 50KB у хендлері, 64KB у nginx (захист від DoS)
- Маршрутизація підпису для кількох репозиторіїв — хендлер шукає кандидатів за
repository.full_name, потім верифікує підпис кожного перед прийняттям (запобігає повторному використанню секрету між проєктами) - Ізоляція публічного ендпоінта — конфіг nginx для
/api/webhooks/githubмаєauth_basic offіproxy_read_timeout 5s
Що ти бачиш у сайдбарі
ContextRail (права панель у робочому просторі) показує розділ GitHub ⤵
- Автоматично ховається, якщо в проєкту немає прив'язаних репозиторіїв
- Останні 8 подій (найновіші першими)
- Іконка для кожної події: GitBranch (push) / GitPullRequest (PR) / CircleCheck (CI success) / CircleAlert (CI failure) / CircleDot (issues)
- Формат відносного часу: 30s, 5m, 2h, 1d
- Клік по рядку → відкриває GitHub URL у новій вкладці
- Опитування кожні 30с (свіжі дані без ручного оновлення)
Повідомлення в Telegram
Master-бот надсилає відформатоване повідомлення власнику проєкту:
🔀 [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). Обробляються лише продакшн-події (push, PR, workflow_run, issues).
Webhook повертає 401 на подію push
- Перевір, що GitHub webhook налаштований із
Content type: application/json(неform-urlencoded) - Перевір secret — він має точно збігатися з тим, що повернув
arc github link - Якщо secret втрачено — видали прив'язку й створи її знову (
arc github unlink→arc github link)
Стрічка в сайдбарі порожня, хоча сповіщення в Telegram приходять
- Перевір, що ContextRail взагалі видно (viewport ≥1280px)
- Зроби hard refresh фронтенду (Ctrl+Shift+R) — компонент кешується
- Перевір DB:
sqlite3 data/citadel.db "SELECT COUNT(*) FROM github_events WHERE project_name='<name>';"
Сповіщення в Telegram не приходять
- Перевір, що в проєкту є
owner_idу DB:sqlite3 ... "SELECT name, owner_id FROM projects;" - Перевір токен master-бота у vault:
grep MASTER_BOT_TOKEN config/vault.json(має бути зашифрований) - Подія вебхука є в DB, але notify впав → перевір логи master:
tmux capture-pane -t citadel-master -p | grep github-notifier
Спрацював rate limit
Жорсткий ліміт 100 req/min/project. Для CI з тисячами ранерів — підніми його в shared/routes/github.ts:RATE_MAX.
API-ендпоінти
Деталі: Довідник API.
| Ендпоінт | 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 | Публічний приймач |
Роадмап
| Phase | Обсяг | Статус |
|---|---|---|
| 49.3 | Приймач вебхуків + Telegram | ✅ DONE |
| 49.3.1 | Стрічка в сайдбарі UI | ✅ DONE |
| 49.4 | API polling, вкладка GitHub у робочому просторі, дашборд для кількох репозиторіїв | BACKLOG (P2) |
| 49.5 | Двостороння синхронізація задач, воркери авто-рев'ю PR | BACKLOG (P2) |