Intégration GitHub — Guide de configuration
Phase 49.3 (Light) — notifications basées sur webhooks + flux sidebar UI pour les repos GitHub liés. Sans synchronisation bidirectionnelle (c'est la Phase 49.5+ Heavy).
Arc OS reçoit les événements webhook des repos GitHub liés et simultanément :
- Envoie une notification Telegram au propriétaire du projet
- Met à jour le flux sidebar dans le ContextRail du Workspace (polling 30s)
Architecture
Repo GitHub
│ (événements push / PR / CI / issue)
▼
arc-os.co/api/webhooks/github
│ Vérification timing-safe HMAC-SHA256 (X-Hub-Signature-256)
│ Limite de débit 100 req/min/projet
│ Payload max 50 Ko
▼
shared/routes/github.ts handleGithubWebhook
├─→ DB : github_events (pour le flux UI)
└─→ shared/github-notifier.ts → Telegram (token master bot)
Événements supportés : push, pull_request, workflow_run, issues. Les autres (releases, deployments, discussions) sont ignorés.
Multi-repo : un projet peut lier plusieurs repos (ex. frontend + backend + docs). Contrainte : UNIQUE(project_name, owner, repo).
Configuration rapide (3 minutes)
1. Génère l'URL webhook + secret
arc github link <nom-du-projet> <owner/repo>
Exemple :
arc github link arc-v2 SerhiiInUa/citadel-v2
Le CLI retournera :
- Webhook URL —
https://arc-os.co/api/webhooks/github - Secret — hex 32 octets (unique pour chaque lien)
- Instructions pas à pas pour l'UI GitHub
2. Ajoute le webhook dans le repo GitHub
Sur la page https://github.com/<owner>/<repo>/settings/hooks :
- Clique sur Add webhook
- Payload URL :
https://arc-os.co/api/webhooks/github - Content type :
application/json(important !) - Secret : colle la valeur depuis la sortie CLI
- Which events? → "Let me select individual events" :
- ☑ Pushes
- ☑ Pull requests
- ☑ Workflow runs
- ☑ Issues
- ☑ Active
- Clique sur Add webhook
GitHub envoie immédiatement un événement ping de test — il sera silencieusement rejeté (car Arc OS n'attend que les types supportés). C'est normal.
3. Vérifie que ça fonctionne
Fais un push dans le repo, ouvre une PR, ou lance un workflow. En ~1-3 secondes :
- Une notification Telegram arrive au propriétaire du projet avec icône + résumé + lien GitHub
- Le flux sidebar dans le ContextRail du Workspace se met à jour (via polling ~30s)
Gestion des liens
Lister les repos liés
arc github links arc-v2
Supprimer un lien
arc github unlink arc-v2 <id>
L'ID est récupéré depuis la sortie arc github links. Le webhook sur GitHub n'est pas supprimé automatiquement — les signatures invalides seront rejetées silencieusement. Meilleur workflow : d'abord supprimer le webhook dans l'UI GitHub, puis arc github unlink.
Sécurité
- Signature HMAC-SHA256 — chaque secret webhook =
crypto.randomBytes(32).toString('hex')(256 bits d'entropie) - Comparaison timing-safe —
node:crypto timingSafeEqualprévient les attaques de timing sur la vérification de signature - Rejet silencieux — les signatures invalides reçoivent
401 ""sans corps (pas de fuite d'info vers les scanners) - Limite de débit — 100 req/min par projet (fenêtre en mémoire). Dépassement →
429 Rate limited - Limite de taille du payload — 50 Ko dans le handler, 64 Ko dans nginx (protection contre le DoS)
- Routage de signature multi-repo — le handler recherche les candidats par
repository.full_name, puis vérifie la signature de chacun avant d'accepter (prévient la réutilisation de secret entre projets) - Isolation des endpoints publics — la config nginx
/api/webhooks/githubaauth_basic offetproxy_read_timeout 5s
Ce que tu vois dans la sidebar
Le ContextRail (panneau droit dans le Workspace) affiche une section GitHub ⤵
- Masqué automatiquement si le projet n'a pas de repos liés
- Les 8 derniers événements (plus récents en premier)
- Icône par événement : GitBranch (push) / GitPullRequest (PR) / CircleCheck (CI succès) / CircleAlert (CI échec) / CircleDot (issues)
- Format de temps relatif : 30s, 5m, 2h, 1j
- Cliquer sur une ligne → ouvre l'URL GitHub dans un nouvel onglet
- Polling toutes les 30s (données fraîches sans rafraîchissement manuel)
Messages Telegram
Le master bot envoie un message formaté au propriétaire du projet :
🔀 [arc-v2] SerhiiInUa/citadel-v2
PR #42 opened: feat: add lazy worker lifecycle by @Sergei89
View on GitHub
Icônes :
- 📦 push
- 🔀 pull_request
- ✅ workflow_run (succès)
- ❌ workflow_run (échec)
- ⚙️ workflow_run (autre)
- 🐛 issues
Dépannage
Le webhook retourne 401 pour le ping de test
Normal — Arc OS rejette silencieusement les événements non supportés (ex. ping). Seuls les événements de production (push, PR, workflow_run, issues) sont traités.
Le webhook retourne 401 pour un événement push
- Vérifie que le webhook GitHub est configuré avec
Content type: application/json(pasform-urlencoded) - Vérifie le secret — il doit correspondre exactement à ce qu'a retourné
arc github link - Si le secret est perdu — supprime le lien et recrée (
arc github unlink→arc github link)
Le flux sidebar est vide alors que Telegram reçoit les notifs
- Vérifie que le ContextRail est visible (viewport ≥ 1280px)
- Hard refresh du frontend (Ctrl+Shift+R) — le composant est mis en cache
- Vérifie la DB :
sqlite3 data/citadel.db "SELECT COUNT(*) FROM github_events WHERE project_name='<name>';"
Telegram ne reçoit pas de notification
- Vérifie que le projet a un
owner_iddans la DB :sqlite3 ... "SELECT name, owner_id FROM projects;" - Vérifie le token master bot dans le vault :
grep MASTER_BOT_TOKEN config/vault.json(doit être chiffré) - L'événement webhook est dans la DB mais la notification a échoué → regarde les logs master :
tmux capture-pane -t citadel-master -p | grep github-notifier
Limite de débit atteinte
Limite stricte de 100 req/min/projet. En cas de CI avec des milliers de runners — augmente dans shared/routes/github.ts:RATE_MAX.
Endpoints API
Détails : Référence API.
| Endpoint | Auth | Description |
|---|---|---|
POST /api/crm/projects/:name/github |
JWT | Lier un repo |
GET /api/crm/projects/:name/github |
JWT | Lister les liens |
DELETE /api/crm/projects/:name/github/:id |
JWT | Délier |
GET /api/crm/projects/:name/github/events?limit=N |
JWT | Lister les événements (max 200) |
POST /api/webhooks/github |
HMAC | Récepteur public |
Roadmap
| Phase | Périmètre | Statut |
|---|---|---|
| 49.3 | Récepteur webhook + Telegram | ✅ FAIT |
| 49.3.1 | Flux sidebar UI | ✅ FAIT |
| 49.4 | Polling API, onglet GitHub Workspace, tableau de bord multi-repo | BACKLOG (P2) |
| 49.5 | Sync bidirectionnelle des tickets, workers auto-review PR | BACKLOG (P2) |