Donner le rôle admin sur un dépôt personnel
💡 Sujet
Sur un dépôt appartenant à un compte personnel (et non à une organisation), promouvoir un
collaborateur en admin par l'API semble impossible : la requête réussit, et rien ne change. La doc
REST entretient la confusion en laissant croire que le rôle admin n'existe pas hors organisation.
Il existe pourtant, et l'API sait le poser — mais seulement à un moment précis du cycle de vie du collaborateur.
🤥 La mise à jour échoue en silence
Sur un collaborateur déjà en place, l'API accepte la demande et l'ignore :
gh api -i -X PUT repos/OWNER/REPO/collaborators/USER -f permission=admin
# HTTP/2.0 204 No Content
gh api repos/OWNER/REPO/collaborators/USER/permission -q .role_name
# write ← inchangéNi erreur, ni avertissement, ni invitation créée. C'est le pire cas de figure : on croit la modification faite. La doc de l'endpoint le dit, en une ligne facile à rater :
The permission to grant the collaborator. Only valid on organization-owned repositories.
✅ La création d'invitation, elle, respecte le paramètre
La restriction ne porte en fait que sur la mise à jour. Si la personne n'est pas encore collaboratrice, le même appel crée une invitation qui, elle, porte bien le rôle demandé :
gh api -X DELETE repos/OWNER/REPO/collaborators/USER # retirer d'abord
gh api -X PUT repos/OWNER/REPO/collaborators/USER -f permission=admin \
-q '"invitation_id=\(.id) permissions=\(.permissions)"'
# invitation_id=327200829 permissions=adminL'invitation doit ensuite être acceptée par l'invité — donc avec son jeton à lui :
gh api -X PATCH /user/repository_invitations/327200829Et le rôle est bien celui demandé :
gh api repos/OWNER/REPO/collaborators/USER/permission -q .role_name
# admin⚠️ Le retrait coupe l'accès pour de bon
Entre le DELETE et l'acceptation, la personne n'a plus aucun accès au dépôt. Si l'invitation
n'est jamais acceptée, elle reste dehors — et sur un dépôt privé, elle ne peut pas se réinviter
elle-même.
Donc : ne lancer la manœuvre qu'en ayant de quoi la terminer, c'est-à-dire un accès admin au dépôt
pour réinviter en cas de besoin. Avec gh, plusieurs comptes peuvent cohabiter et on choisit lequel
répond, sans changer le compte actif :
GH_TOKEN=$(gh auth token -u autre-compte) gh api …🔬 Vérifier le rôle, pas l'étiquette
role_name vient de la même API que celle qui a menti par omission. Le contrôle honnête est
d'appeler quelque chose que seul un admin a le droit de faire :
gh api repos/OWNER/REPO/invitations # 403 "Must have admin rights" si le rôle n'a pas pris📦 Le cas qui amène là : le transfert de dépôt
Transférer un dépôt personnel vers un autre compte reconduit l'ancien propriétaire et les collaborateurs — mais en écriture. L'ancien propriétaire perd donc ses droits d'administration sur son propre dépôt, et les récupérer passe exactement par la manœuvre ci-dessus.
À savoir aussi sur le transfert : le nouveau propriétaire doit l'accepter, et l'invitation expire au bout d'un jour.
🧩 Résumé
- 🤥
PUT …/collaborators/USER -f permission=adminsur un collaborateur existant d'un dépôt personnel :204 No Content, aucun effet. - ✅ Le même appel sur un non-collaborateur crée une invitation qui porte le rôle : retirer, puis réinviter.
- 🔑 L'invitation s'accepte avec le jeton de l'invité :
PATCH /user/repository_invitations/{id}. - ⚠️ Entre les deux, l'accès est coupé — garder de quoi réinviter.
- 🔬 Valider avec un appel réservé aux admins, pas avec
role_name. - 📦 Un transfert de dépôt reconduit l'ancien propriétaire en écriture seulement.