- Lors de l’utilisation de l’API GitHub, un problème d’incompatibilité d’ID a empêché le bon fonctionnement d’une fonction de génération de liens vers des commentaires de PR
- L’enquête a révélé que GitHub utilise en parallèle deux systèmes d’ID : le node ID de GraphQL et le database ID de l’API REST
- Après décodage base64 du node ID, il a été confirmé que les 32 bits de poids faible contiennent le database ID, ce qui permet une conversion via une simple opération de masque binaire
- Une analyse supplémentaire a montré que GitHub mélange un nouveau format d’ID basé sur MessagePack et un ancien format textuel
- Cette structure met en évidence la dualité du système d’identification interne des objets de GitHub et demande de la prudence lors de l’intégration des API
Découverte du système à double ID de GitHub
- Lors du développement d’une fonctionnalité de l’outil de revue de code par IA de Greptile, un problème est apparu : les liens vers les commentaires de PR sur GitHub ne fonctionnaient pas
- L’ID du commentaire enregistré avait bien été injecté dans l’URL, mais un clic ne menait pas à la page GitHub attendue
- La documentation GitHub montre que le node ID de l’API GraphQL et le database ID de l’API REST reposent sur deux systèmes distincts
- Exemple de node ID :
PRRC_kwDOL4aMSs6Tkzl8
- Exemple de database ID :
2475899260
- Le node ID est une chaîne encodée en base64 servant à identifier globalement un objet dans GitHub, tandis que le database ID est utilisé comme identifiant entier dans les URL
Analyse de la relation entre node ID et database ID
- En comparant les node ID et database ID de plusieurs commentaires de PR, il a été constaté que les deux valeurs augmentent selon un intervalle régulier
- Le décodage de la partie base64 du node ID produit un entier de 96 bits, dont les 32 bits de poids faible correspondent au database ID
- Exemple :
PRRC_kwDOL4aMSs6Tkzl8 → 32 bits de poids faible = 2475899260
- Il est possible d’extraire le database ID avec une simple opération de masque binaire
- Conversion via une expression du type
decoded & ((1 << 32) - 1)
Le format d’ID legacy de GitHub
- En décodant le node ID d’un ancien dépôt (
torvalds/linux), on obtient une chaîne dans un format différent
- Exemple :
MDEwOlJlcG9zaXRvcnkyMzI1Mjk4 → 010:Repository2325298
- Ce format suit la structure
[numéro de type d’objet]:[nom de l’objet][Database ID] et constitue un identifiant explicite basé sur une chaîne
- Dans le cas d’un objet arbre, on obtient une forme comme
04:Tree2325298:7201bfb9..., qui inclut à la fois l’ID du dépôt et la valeur SHA
- GitHub utilise à la fois le format legacy et le nouveau format, selon le type d’objet et sa date de création
Structure du nouveau format de node ID
- Le guide de migration GraphQL de GitHub indique qu’il faut traiter le node ID comme une chaîne opaque, mais une structure interne existe bien
- Après décodage base64 puis dépaquetage avec MessagePack, les données apparaissent sous forme de tableau
- Exemple :
[0, 47954445, 2475899260]
- Composition du tableau
- Premier élément (0) : probablement un identifiant de version
- Deuxième élément (47954445) : le database ID du dépôt
- Troisième élément (2475899260) : le database ID de l’objet
- La longueur du tableau varie selon le type d’objet : les commits incluent le SHA, tandis que les dépôts ne contiennent que deux éléments
Utilisation pratique et conclusion
Aucun commentaire pour le moment.