Intégration GitHub — Guide de configuration
Phase 49.3 (Light) — notifications par webhook + feed dans la sidebar de l'UI pour les repos GitHub liés. Pas de sync 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 feed de la sidebar dans le ContextRail du Workspace (polling 30s)
Architecture
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)
Événements supportés : push, pull_request, workflow_run, issues. Le reste (releases, deployments, discussions) est ignoré.
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+secret du webhook
arc github link <project-name> <owner/repo>
Exemple :
arc github link arc-v2 SerhiiInUa/citadel-v2
Le CLI renvoie :
- URL du webhook —
https://arc-os.co/api/webhooks/github - Secret — hex de 32 octets (unique par 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 de la sortie du 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 de test ping — il sera silencieusement rejeté (car ARC n'attend que les types supportés). C'est normal.
3. Vérifie que ça fonctionne
Pousse sur le repo, ouvre une PR, ou lance un workflow. En ~1-3 secondes :
- Une notification Telegram arrive pour le propriétaire du projet avec icône + résumé + lien GitHub
- Le feed de la sidebar dans le ContextRail du Workspace se met à jour (via polling ~30s)
Gérer les liens
Lister les repos liés
arc github links arc-v2
Retirer un lien
arc github unlink arc-v2 <id>
L'ID vient de la sortie de arc github links. Le webhook sur GitHub n'est pas supprimé automatiquement — les signatures invalides seront silencieusement rejetées. Meilleur workflow : supprime d'abord le webhook dans l'UI GitHub, puis arc github unlink.
Sécurité
- Signature HMAC-SHA256 — chaque secret de webhook =
crypto.randomBytes(32).toString('hex')(256 bits d'entropie) - Comparaison timing-safe —
node:crypto timingSafeEqualempêche 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) - Rate limit — 100 req/min par projet (fenêtre en mémoire). Dépassement →
429 Rate limited - Limite de taille du payload — 50KB dans le handler, 64KB dans nginx (protection 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 (empêche la réutilisation de secret cross-projet) - Isolation de l'endpoint public — la config nginx pour
/api/webhooks/githubaauth_basic offetproxy_read_timeout 5s
Ce que tu vois dans la sidebar
Le ContextRail (panneau de droite dans le Workspace) affiche la section GitHub ⤵
- Masquée automatiquement si le projet n'a aucun repo lié
- 8 derniers événements (plus récents d'abord)
- Icône par événement : GitBranch (push) / GitPullRequest (PR) / CircleCheck (succès CI) / CircleAlert (échec CI) / CircleDot (issues)
- Format de temps relatif : 30s, 5m, 2h, 1d
- Clique 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 renvoie 401 sur le ping de test
Attendu — ARC 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 renvoie 401 sur 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 renvoyé
arc github link - Si le secret est perdu — supprime le lien et recrée-le (
arc github unlink→arc github link)
Le feed de la sidebar est vide alors que les notifications Telegram arrivent
- Vérifie que le ContextRail est visible (viewport ≥1280px)
- Fais un hard refresh du frontend (Ctrl+Shift+R) — le composant est en cache
- Vérifie la DB :
sqlite3 data/citadel.db "SELECT COUNT(*) FROM github_events WHERE project_name='<name>';"
Les notifications Telegram n'arrivent pas
- Vérifie que le projet a un
owner_iden DB :sqlite3 ... "SELECT name, owner_id FROM projects;" - Vérifie le token du master bot dans le vault :
grep MASTER_BOT_TOKEN config/vault.json(doit être chiffré) - L'événement webhook est en DB mais le notify a échoué → vérifie les logs du master :
tmux capture-pane -t citadel-master -p | grep github-notifier
Rate limit atteint
Limite stricte 100 req/min/projet. Pour la CI avec des milliers de runners — augmente-la 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 de webhook + Telegram | ✅ TERMINÉ |
| 49.3.1 | Feed de la sidebar UI | ✅ TERMINÉ |
| 49.4 | Polling API, onglet GitHub du Workspace, dashboard multi-repo | BACKLOG (P2) |
| 49.5 | Sync bidirectionnelle des issues, workers de review auto-PR | BACKLOG (P2) |