Revues de code automatiques avec CODEOWNERS
Configurez CODEOWNERS sur GitHub, évitez les échecs silencieux et imposez la revue avec les bons motifs, droits et protections de branche.
Un fichier CODEOWNERS est un fichier texte brut dans votre dépôt qui associe des modèles de chemins à des propriétaires — utilisateurs ou équipes GitHub — et demande automatiquement une revue de leur part dès qu’une pull request touche un chemin correspondant. Il remplit deux fonctions simultanément : il achemine les revues vers les bonnes personnes sans que personne ait à les solliciter manuellement, et il documente qui est responsable de quoi. Le problème, c’est que CODEOWNERS échoue silencieusement. Un ordre de patterns incorrect, une équipe sans membres, ou un propriétaire sans accès en écriture ne génère aucun message d’erreur — la demande de revue ne se déclenche tout simplement pas, et la PR est fusionnée sans les regards que vous souhaitiez.
Ce guide vous permet de configurer le tout correctement en quelques minutes, puis consacre l’essentiel du temps aux pièges : la règle du dernier pattern gagnant qui écrase silencieusement vos règles spécifiques, ainsi que les échecs liés aux permissions, aux équipes vides et à la branche par défaut, qui donnent l’impression que CODEOWNERS est configuré alors qu’il ne fait rien.
Points clés à retenir
- CODEOWNERS applique la règle du dernier pattern gagnant : lorsque plusieurs patterns correspondent à un fichier, seule la dernière ligne correspondante assigne des propriétaires — placez les règles générales en haut et les remplacements spécifiques en bas.
- Le fichier doit se trouver sur la branche de base de la PR, peser moins de 3 Mo, respecter la casse, et contenir une syntaxe valide ; toute ligne invalide est silencieusement ignorée.
- CODEOWNERS seul ne bloque pas les fusions — vous devez également activer « Require a pull request before merging » et « Require review from Code Owners » dans un ruleset ou une règle de protection de branche.
- Un propriétaire sans accès en écriture est silencieusement ignoré, et une équipe propriétaire doit elle-même être visible et disposer d’un accès en écriture, même si chacun de ses membres en dispose déjà individuellement.
- GitHub CODEOWNERS ne prend pas en charge la négation avec
!— les patterns comme!README.mdsont rejetés comme invalides.
À quoi sert un fichier CODEOWNERS ?
CODEOWNERS désigne les individus ou équipes responsables de chemins spécifiques dans un dépôt. Lorsqu’une personne ouvre une pull request qui modifie un chemin correspondant, GitHub demande automatiquement une revue aux propriétaires listés. Le même format de fichier fonctionne sur GitHub, GitLab et Bitbucket ; les exemples ici sont orientés GitHub en priorité.
Avec une part croissante de PRs rédigées par des agents IA, une règle CODEOWNERS sur les chemins sensibles — auth/, **/migrations/, la configuration CI — garantit qu’un propriétaire humain examine encore les modifications des agents avant qu’elles ne soient intégrées.
Discover how at OpenReplay.com.
Comment configurer et appliquer CODEOWNERS ?
Placez le fichier dans .github/CODEOWNERS. GitHub cherche d’abord dans .github/, puis à la racine du dépôt, puis dans docs/, et utilise le premier fichier CODEOWNERS trouvé — un emplacement canonique unique évite toute confusion. Rédigez une règle par ligne sous la forme pattern @propriétaire, puis validez-la sur votre branche par défaut.
# .github/CODEOWNERS
# Propriétaires par défaut pour tout le dépôt
* @my-org/core-team
# Frontend et backend par domaine
/src/frontend/ @my-org/frontend-team
/src/backend/ @my-org/backend-team
# Tests et documentation
**/tests/ @my-org/qa-team
*.md @my-org/docs-team
# Les chemins sensibles ont un propriétaire dédié (à placer en dernier)
/src/auth/ @my-org/security-team
Déployez-le comme n’importe quel autre fichier :
git add .github/CODEOWNERS
git commit -m "Add CODEOWNERS"
git push origin main
Valider le fichier ne fait que demander des relecteurs — cela ne bloque rien. Pour réellement conditionner les fusions, activez deux paramètres conjointement : Require a pull request before merging et Require review from Code Owners. Vous pouvez les configurer dans les nouveaux Rulesets (Settings → Rules → Rulesets) ou dans une règle de protection de branche classique (Settings → Branches). Les deux interfaces sont disponibles ; les rulesets constituent la surface la plus récente.
Patterns de syntaxe CODEOWNERS à connaître
Le langage de patterns suit la plupart des règles gitignore. Ces cinq exemples couvrent presque tous les cas :
* @core-team # valeur par défaut globale
/api/ @backend-team # un répertoire
*.ts @frontend-team # une extension, à n'importe quelle profondeur
**/tests/ @qa-team # répertoire imbriqué, n'importe où
/security/ @sec-team @compliance-team # deux propriétaires, une seule ligne
Un glob d’extension non ancré comme *.ts correspond aux fichiers de ce type n’importe où dans le dépôt — il se comporte de la même manière que **/*.ts. Une règle s’applique lorsqu’on liste plusieurs propriétaires : tous doivent figurer sur la même ligne. Si vous les répartissez sur plusieurs lignes, le pattern ne retient que le dernier propriétaire mentionné. Lorsque la revue par les propriétaires de code est requise, l’approbation d’un seul des propriétaires listés suffit à satisfaire l’exigence.
Un mythe à déconstruire : contrairement à .gitignore, GitHub CODEOWNERS ne prend pas en charge la négation avec !. Les patterns comme !README.md sont rejetés comme invalides — la documentation officielle de GitHub liste !, les plages de caractères [ ] et l’échappement \# comme des fonctionnalités gitignore qui ne fonctionnent pas ici. Pour exclure un chemin, assignez-lui un propriétaire différent ou organisez les règles de façon qu’aucune ne le corresponde (laisser la colonne propriétaire vide sur une ligne ultérieure plus spécifique supprime la propriété pour ce chemin).
La règle du dernier pattern gagnant (l’erreur n°1)
CODEOWNERS applique la règle du dernier pattern gagnant : lorsque plusieurs patterns correspondent à un fichier, seule la dernière ligne correspondante assigne des propriétaires. L’ordre est la cause d’échec la plus fréquente. Placez les règles générales en haut et les remplacements spécifiques en bas.
Voici l’ordre incorrect — le catch-all arrive en dernier et s’approprie silencieusement tout :
# INCORRECT — * est le dernier pattern correspondant, donc @core-team possède aussi /src/auth/
/src/auth/ @security-team
* @core-team
Parce que * correspond à /src/auth/app.ts et apparaît plus loin dans le fichier, @security-team n’est jamais sollicité. Inversez l’ordre :
# CORRECT — général en premier, remplacement spécifique en dernier
* @core-team
/src/auth/ @security-team
Désormais, une modification sous /src/auth/ sollicite @security-team, et tout le reste revient à @core-team. Vérifiez l’ordre des patterns à chaque ajout de règle.
Pourquoi CODEOWNERS ne se déclenche pas silencieusement
La plupart des signalements du type « c’est configuré mais rien ne se passe » se ramènent à l’un de ces cas. CODEOWNERS est lu depuis la branche de base de la pull request, est sensible à la casse, doit peser moins de 3 Mo, et ignore toute ligne dont la syntaxe est invalide — un fichier qui semble correct peut donc ne déclencher aucune revue.
| Symptôme | Cause | Correction |
|---|---|---|
| Aucun relecteur demandé | Le fichier n’est pas sur la branche de base de la PR | Validez CODEOWNERS sur la branche vers laquelle vous fusionnez |
| Une règle spécifique ne se déclenche jamais | Dernier pattern gagnant — un pattern ultérieur la remplace | Remontez les règles générales, descendez les règles spécifiques |
| Une ligne ignorée, les autres fonctionnent | Syntaxe invalide sur cette ligne — elle est silencieusement ignorée | Ouvrez le fichier sur GitHub ; un lien « Syntax errors » signale les lignes problématiques |
| Propriétaire listé mais jamais sollicité | Le propriétaire n’a pas d’accès en écriture, ou l’utilisateur/l’équipe n’existe pas | Accordez l’accès en écriture ; vérifiez l’identifiant |
| Fusion bloquée, personne ne peut approuver | Une équipe vide possède le chemin | Ajoutez au moins un membre à l’équipe |
| Le chemin ne correspond à rien | Aucune règle ne le couvre | Ajoutez une règle, ou acceptez l’approbation de tout contributeur avec accès en écriture |
| Pas de demande sur une draft PR | Les draft PRs ne déclenchent pas les demandes de propriétaires de code | Marquez la PR comme prête pour revue |
| Règle ignorée sur un fichier volumineux | CODEOWNERS de plus de 3 Mo n’est pas chargé | Consolidez les entrées avec des wildcards |
Deux détails de permissions sont à l’origine de la plupart des échecs silencieux. Les personnes désignées comme propriétaires de code doivent disposer d’autorisations en écriture — un propriétaire sans accès en écriture est silencieusement ignoré. Et lorsque le propriétaire est une équipe, celle-ci doit elle-même être visible et disposer d’un accès en écriture, même si chacun de ses membres en dispose déjà individuellement. Si vous nommez un utilisateur ou une équipe qui n’existe pas ou n’a pas accès, aucun propriétaire de code n’est assigné — sans aucun avertissement sur la PR. GitHub signale toutefois les lignes problématiques : ouvrez le fichier CODEOWNERS dans l’interface du dépôt pour voir les erreurs surlignées, également accessibles via l’API REST.
Au-delà de l’assignation statique : auto-assignation d’équipe et Actions
CODEOWNERS associe statiquement des chemins à des propriétaires. Deux mécanismes l’étendent lorsque cela ne suffit pas.
L’auto-assignation d’équipe intégrée vous évite de solliciter toute une équipe. Sous Organization → Teams → équipe → Settings → Code review, activez l’auto-assignation : chaque fois que l’équipe est sollicitée, la demande adressée à l’équipe entière est remplacée par une demande adressée à un sous-ensemble de membres. Choisissez round robin, qui fait tourner selon la demande la moins récente, ou load balance, qui équilibre le total des demandes récentes de chaque membre. Notez une interaction particulière : lorsqu’un propriétaire de code est requis par la protection de branche, la demande adressée à l’équipe ne peut pas être supprimée, de sorte que la demande individuelle s’ajoute à celle de l’équipe.
Faites appel à GitHub Actions uniquement lorsque l’assignation doit dépendre du diff ou d’un label — quelque chose que CODEOWNERS ne peut pas exprimer. Un workflow minimal utilisant actions/checkout (dernière version v7.0.0, publiée le 18 juin 2026) avec une action d’assignation de relecteurs sur le déclencheur pull_request standard :
name: Assign Reviewers
on:
pull_request:
types: [opened, ready_for_review]
permissions:
pull-requests: write
jobs:
assign:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0 # nécessaire pour git diff entre les branches
# ...associez ici les chemins modifiés ou les labels aux relecteurs
Utilisez l’échelle d’escalade comme guide de décision, non comme un menu : CODEOWNERS pour les règles statiques chemin→propriétaire, l’auto-assignation d’équipe pour répartir la charge au sein d’une équipe, Actions pour la logique basée sur les modifications ou les labels.
Commencez par un seul .github/CODEOWNERS sur votre branche par défaut, ordonnez-le du général au spécifique, activez « Require review from Code Owners », puis ouvrez une PR de test et vérifiez que le propriétaire attendu est bien sollicité — cette seule vérification permet de détecter les échecs silencieux avant qu’ils n’atteignent la production.
FAQ
Quelle est la différence entre CODEOWNERS et l'auto-assignation de revue de code d'équipe de GitHub ?
CODEOWNERS est un fichier statique qui associe des patterns de chemins à des propriétaires et demande une revue dès qu'une PR touche un chemin correspondant. L'auto-assignation d'équipe est un paramètre d'organisation qui, une fois qu'une équipe est sollicitée, remplace la demande adressée à l'équipe entière par une demande adressée à un sous-ensemble de membres choisis par round robin ou load balance. Les deux fonctionnent ensemble : CODEOWNERS détermine quelle équipe possède un chemin, et l'auto-assignation détermine quels membres de cette équipe sont effectivement sollicités.
Puis-je exclure un fichier spécifique d'une règle CODEOWNERS en utilisant la négation comme dans gitignore ?
Non. GitHub CODEOWNERS ne prend pas en charge la négation, donc un pattern comme '!README.md' est rejeté comme invalide et la ligne est silencieusement ignorée. La documentation de GitHub liste la négation '!', les plages de caractères '[ ]' et l'échappement '#' comme des fonctionnalités gitignore qui ne fonctionnent pas ici. Pour exclure un chemin, ajoutez une règle ultérieure plus spécifique lui assignant un propriétaire différent, ou laissez la colonne propriétaire vide sur cette ligne spécifique pour supprimer la propriété.
Pourquoi les propriétaires de code ne sont-ils pas sollicités sur ma pull request alors que le fichier semble correct ?
La cause la plus fréquente est que CODEOWNERS est lu depuis la branche de base de la PR — un fichier présent uniquement sur votre branche de fonctionnalité ne se déclenche jamais. Parmi les autres causes silencieuses : un propriétaire sans accès en écriture, une équipe propriétaire non visible ou sans accès en écriture, une équipe vide, une draft PR (qui ne déclenche jamais les demandes de propriétaires de code), un fichier de plus de 3 Mo, des chemins avec une casse incorrecte, ou une ligne invalide que GitHub ignore sans avertissement.
CODEOWNERS bloque-t-il les fusions par lui-même, ou ai-je besoin d'une protection de branche ?
CODEOWNERS seul ne fait que demander des relecteurs ; il ne bloque jamais une fusion. Pour conditionner les fusions, vous devez également activer deux paramètres conjointement : 'Require a pull request before merging' et 'Require review from Code Owners'. Configurez-les dans un ruleset sous Settings, Rules, Rulesets, ou dans une règle de protection de branche classique sous Settings, Branches. Les deux interfaces sont disponibles, les rulesets constituant la voie la plus récente.