12k
All articles

Automatische Code-Reviews mit CODEOWNERS

Richten Sie GitHub CODEOWNERS ein, vermeiden Sie stille Fehler und erzwingen Sie Code-Review mit passenden Mustern, Rechten und Branch-Schutz.

OpenReplay Team
OpenReplay Team
Automatische Code-Reviews mit CODEOWNERS

Eine CODEOWNERS-Datei ist eine Klartextdatei in Ihrem Repository, die Pfadmuster auf Eigentümer abbildet – GitHub-Benutzer oder Teams – und automatisch eine Review von diesen Eigentümern anfordert, sobald ein Pull Request einen übereinstimmenden Pfad berührt. Sie erfüllt dabei zwei Aufgaben gleichzeitig: Sie leitet Reviews an die richtigen Personen weiter, ohne dass jemand manuell benachrichtigt werden muss, und sie dokumentiert, wer für was verantwortlich ist. Der Haken dabei ist, dass CODEOWNERS lautlos versagt. Eine falsche Musterreihenfolge, ein Team ohne Mitglieder oder ein Eigentümer ohne Schreibzugriff erzeugt keinen Fehlerdialog – die Review-Anfrage wird einfach nicht ausgelöst, und der PR wird ohne die gewünschten Augen gemergt.

Diese Anleitung erklärt die Einrichtung in wenigen Minuten und widmet sich dann ausführlich den Fallstricken: der Last-Match-Wins-Regel, die Ihre spezifischen Regeln stillschweigend überschreibt, sowie den Berechtigungs-, Leerteam- und Standard-Branch-Fehlern, die CODEOWNERS konfiguriert erscheinen lassen, obwohl es nichts tut.

Die wichtigsten Erkenntnisse

  • CODEOWNERS arbeitet nach dem Last-Match-Wins-Prinzip: Wenn mehrere Muster auf eine Datei zutreffen, weist nur die letzte übereinstimmende Zeile Eigentümer zu – platzieren Sie allgemeine Regeln oben und spezifische Überschreibungen unten.
  • Die Datei muss sich auf dem Base-Branch des PRs befinden, unter 3 MB groß sein, die korrekte Groß-/Kleinschreibung verwenden und gültige Syntax enthalten; jede ungültige Zeile wird stillschweigend übersprungen.
  • CODEOWNERS allein blockiert keine Merges – Sie müssen zusätzlich „Require a pull request before merging” und „Require review from Code Owners” in einem Ruleset oder einer Branch-Protection-Regel aktivieren.
  • Ein Eigentümer ohne Schreibzugriff wird stillschweigend ignoriert, und ein Team-Eigentümer muss selbst sichtbar sein und Schreibzugriff besitzen, auch wenn jedes Mitglied diesen bereits individuell hat.
  • GitHub CODEOWNERS unterstützt keine !-Negation – Muster wie !README.md werden als ungültig abgelehnt.

Was bewirkt eine CODEOWNERS-Datei?

CODEOWNERS legt fest, welche Personen oder Teams für bestimmte Pfade in einem Repository verantwortlich sind. Wenn jemand einen Pull Request öffnet, der einen übereinstimmenden Pfad ändert, fordert GitHub automatisch eine Review von den aufgeführten Eigentümern an. Das gleiche Dateiformat funktioniert auf GitHub, GitLab und Bitbucket; die Beispiele hier sind primär auf GitHub ausgerichtet.

Da ein wachsender Anteil von PRs von KI-Agenten erstellt wird, stellt eine CODEOWNERS-Regel für sensible Pfade – auth/, **/migrations/, CI-Konfiguration – sicher, dass ein menschlicher Eigentümer Änderungen durch Agenten noch vor dem Einpflegen überprüft.

Wie richtet man CODEOWNERS ein und setzt es durch?

Legen Sie die Datei unter .github/CODEOWNERS ab. GitHub sucht zunächst in .github/, dann im Repository-Stammverzeichnis und anschließend in docs/ und verwendet die erste gefundene CODEOWNERS-Datei. Ein einziger kanonischer Speicherort verhindert daher Verwirrung. Schreiben Sie eine Regel pro Zeile im Format Muster @Eigentümer und committen Sie die Datei dann in Ihren Standard-Branch.

# .github/CODEOWNERS
# Standardeigentümer für alles im Repository
*                   @my-org/core-team

# Frontend und Backend nach Bereich
/src/frontend/      @my-org/frontend-team
/src/backend/       @my-org/backend-team

# Tests und Dokumentation
**/tests/           @my-org/qa-team
*.md                @my-org/docs-team

# Sensible Pfade erhalten einen dedizierten Eigentümer (diese zuletzt platzieren)
/src/auth/          @my-org/security-team

Committen Sie die Datei wie jede andere:

git add .github/CODEOWNERS
git commit -m "Add CODEOWNERS"
git push origin main

Das Committen der Datei fordert lediglich Reviewer an – es blockiert nichts. Um Merges tatsächlich zu sperren, müssen zwei Einstellungen gemeinsam aktiviert werden: Require a pull request before merging und Require review from Code Owners. Diese können Sie in den neueren Rulesets (Settings → Rules → Rulesets) oder in einer klassischen Branch-Protection-Regel (Settings → Branches) konfigurieren. Beide Wege sind verfügbar; Rulesets ist die neuere Oberfläche.

Wissenswerte CODEOWNERS-Syntaxmuster

Die Mustersprache folgt größtenteils den gitignore-Regeln. Diese fünf Muster decken nahezu alles ab:

*                   @core-team      # globaler Standard
/api/               @backend-team   # ein Verzeichnis
*.ts                @frontend-team  # eine Dateiendung, auf beliebiger Tiefe
**/tests/           @qa-team        # verschachteltes Verzeichnis an beliebiger Stelle
/security/          @sec-team @compliance-team   # zwei Eigentümer, eine Zeile

Ein nicht verankerter Erweiterungsglob wie *.ts stimmt mit Dateien dieses Typs überall im Repository überein – er verhält sich genauso wie **/*.ts. Eine Regel ist beim Auflisten mehrerer Eigentümer zu beachten: Alle Eigentümer müssen in derselben Zeile stehen. Werden sie auf mehrere Zeilen aufgeteilt, stimmt das Muster nur mit dem zuletzt genannten Eigentümer überein. Wenn eine Review von Code-Eigentümern erforderlich ist, reicht die Genehmigung von einem einzigen der aufgeführten Eigentümer aus, um die Anforderung zu erfüllen.

Ein weit verbreiteter Irrtum sei hier ausgeräumt: Im Gegensatz zu .gitignore unterstützt GitHub CODEOWNERS keine !-Negation. Muster wie !README.md werden als ungültig abgelehnt – Githubs eigene Dokumentation listet !, [ ]-Zeichenbereiche und \#-Escaping als gitignore-Funktionen auf, die hier nicht funktionieren. Um einen Pfad auszuschließen, weisen Sie ihm einen anderen Eigentümer zu oder ordnen Sie die Regeln so an, dass keine auf ihn zutrifft (eine leere Eigentümerspalte in einer späteren, spezifischeren Zeile hebt die Eigentümerschaft für diesen Pfad auf).

Die Last-Match-Wins-Regel (Fehler Nr. 1)

CODEOWNERS arbeitet nach dem Last-Match-Wins-Prinzip: Wenn mehrere Muster auf eine Datei zutreffen, weist nur die letzte übereinstimmende Zeile Eigentümer zu. Die Reihenfolge ist der mit Abstand häufigste Fehler. Platzieren Sie allgemeine Regeln oben und spezifische Überschreibungen unten.

Hier ist die fehlerhafte Reihenfolge – der Catch-All steht zuletzt und beansprucht stillschweigend alles:

# FALSCH — * ist die letzte Übereinstimmung, daher gehört /src/auth/ ebenfalls @core-team
/src/auth/          @security-team
*                   @core-team

Da * auf /src/auth/app.ts zutrifft und später in der Datei erscheint, wird @security-team nie angefordert. Drehen Sie die Reihenfolge um:

# RICHTIG — allgemein zuerst, spezifische Überschreibung zuletzt
*                   @core-team
/src/auth/          @security-team

Jetzt fordert eine Änderung unter /src/auth/ den @security-team an, und alles andere fällt auf @core-team zurück. Überprüfen Sie die Musterreihenfolge jedes Mal, wenn Sie eine Regel hinzufügen.

Warum CODEOWNERS lautlos nicht ausgelöst wird

Die meisten Meldungen nach dem Muster „Es ist konfiguriert, aber nichts passiert” lassen sich auf einen dieser Gründe zurückführen. CODEOWNERS wird vom Base-Branch des Pull Requests gelesen, unterscheidet zwischen Groß- und Kleinschreibung, muss unter 3 MB groß sein und überspringt jede Zeile mit ungültiger Syntax – eine Datei, die korrekt aussieht, kann also trotzdem null Reviews auslösen.

SymptomUrsacheLösung
Kein Reviewer wird angefordertDatei nicht auf dem Base-Branch des PRsCODEOWNERS in den Branch committen, in den gemergt wird
Eine bestimmte Regel greift nieLast-Match-Wins – ein späteres Muster überschreibt sieAllgemeine Regeln nach oben, spezifische nach unten verschieben
Eine Zeile wird ignoriert, der Rest funktioniertUngültige Syntax in dieser Zeile – sie wird stillschweigend übersprungenDatei auf GitHub öffnen; ein „Syntax errors”-Link markiert fehlerhafte Zeilen
Eigentümer aufgeführt, aber nie angefragtEigentümer hat keinen Schreibzugriff oder Benutzer/Team existiert nichtSchreibzugriff gewähren; Handle überprüfen
Merge blockiert, niemand kann genehmigenLeeres Team besitzt den PfadMindestens ein Mitglied zum Team hinzufügen
Pfad stimmt mit nichts übereinKeine Regel deckt ihn abRegel hinzufügen oder Genehmigung durch beliebigen Schreibberechtigten akzeptieren
Keine Anfrage bei einem Draft-PRDraft-PRs lösen keine Code-Owner-Anfragen ausPR als bereit zur Review markieren
Regel wird bei einer großen Datei ignoriertCODEOWNERS über 3 MB wird nicht geladenEinträge mit Wildcards zusammenfassen

Zwei Berechtigungsdetails verursachen den Großteil der stillen Fehler. Die als Code-Eigentümer ausgewählten Personen müssen Schreibberechtigungen besitzen – ein Eigentümer ohne Schreibzugriff wird stillschweigend ignoriert. Und wenn der Eigentümer ein Team ist, muss dieses Team selbst sichtbar sein und Schreibzugriff haben, auch wenn jedes Mitglied diesen bereits individuell besitzt. Wird ein Benutzer oder Team angegeben, das nicht existiert oder keinen Zugriff hat, wird kein Code-Eigentümer zugewiesen – ohne jede Warnung im PR. GitHub zeigt fehlerhafte Zeilen jedoch an: Öffnen Sie die CODEOWNERS-Datei in der Repository-Oberfläche, um hervorgehobene Fehler zu sehen, die auch über die REST-API abrufbar sind.

Über statische Zuweisung hinaus: Team-Auto-Assign und Actions

CODEOWNERS bildet Pfade statisch auf Eigentümer ab. Zwei Mechanismen erweitern dies, wenn das nicht ausreicht.

Die integrierte Team-Auto-Zuweisung verhindert, dass ein gesamtes Team benachrichtigt wird. Unter Organisation → Teams → Team → Settings → Code review aktivieren Sie die automatische Zuweisung: Sobald das Team angefragt wird, wird die Anfrage an das gesamte Team entfernt und stattdessen einer Teilmenge von Mitgliedern zugewiesen. Wählen Sie Round Robin, das nach der am längsten zurückliegenden Anfrage rotiert, oder Load Balance, das die Gesamtzahl der aktuellen Anfragen je Mitglied ausgleicht. Beachten Sie eine Wechselwirkung: Wenn ein Code-Eigentümer durch Branch-Protection vorgeschrieben ist, kann die Team-Anfrage nicht entfernt werden, sodass die individuelle Anfrage zusätzlich zur Team-Anfrage erscheint.

Greifen Sie auf GitHub Actions zurück, wenn die Zuweisung vom Diff oder einem Label abhängen muss – etwas, das CODEOWNERS nicht ausdrücken kann. Ein minimaler Workflow mit actions/checkout (neueste Version v7.0.0, veröffentlicht am 18. Juni 2026) sowie einer Reviewer-Zuweisungs-Action beim einfachen pull_request-Trigger:

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   # erforderlich für git diff über Branches hinweg
      # ...hier geänderte Pfade oder Labels auf Reviewer abbilden

Verwenden Sie die Eskalationsleiter als Entscheidungshilfe, nicht als Menü: CODEOWNERS für statische Pfad-zu-Eigentümer-Regeln, Team-Auto-Assign zur Lastverteilung innerhalb eines Teams, Actions für diff- oder labelbasierte Logik.

Beginnen Sie mit einer einzigen .github/CODEOWNERS-Datei auf Ihrem Standard-Branch, ordnen Sie sie von allgemein nach spezifisch, aktivieren Sie „Require review from Code Owners”, öffnen Sie dann einen Test-PR und bestätigen Sie, dass der erwartete Eigentümer angefragt wird – diese eine Prüfung deckt die stillen Fehler auf, bevor sie in die Produktion gelangen.

Häufig gestellte Fragen

Was ist der Unterschied zwischen CODEOWNERS und GitHubs Team-Code-Review-Auto-Zuweisung?

CODEOWNERS ist eine statische Datei, die Pfadmuster auf Eigentümer abbildet und eine Review anfordert, sobald ein PR einen übereinstimmenden Pfad berührt. Die Team-Auto-Zuweisung ist eine Organisationseinstellung, die – sobald ein Team angefragt wird – die Anfrage an das gesamte Team durch eine Teilmenge von Mitgliedern ersetzt, die per Round Robin oder Load Balance ausgewählt werden. Beide arbeiten zusammen: CODEOWNERS entscheidet, welches Team einen Pfad besitzt, und die Auto-Zuweisung entscheidet, welche Mitglieder dieses Teams tatsächlich benachrichtigt werden.

Kann ich eine bestimmte Datei mit Negation wie in gitignore von einer CODEOWNERS-Regel ausschließen?

Nein. GitHub CODEOWNERS unterstützt keine Negation, daher wird ein Muster wie '!README.md' als ungültig abgelehnt und die Zeile stillschweigend übersprungen. GitHubs Dokumentation listet '!'-Negation, '[ ]'-Zeichenbereiche und '#'-Escaping als gitignore-Funktionen auf, die hier nicht funktionieren. Um einen Pfad auszuschließen, fügen Sie eine spätere, spezifischere Regel hinzu, die ihm einen anderen Eigentümer zuweist, oder lassen Sie die Eigentümerspalte in dieser spezifischen Zeile leer, um die Eigentümerschaft dafür aufzuheben.

Warum werden bei meinem Pull Request keine Code-Eigentümer angefragt, obwohl die Datei korrekt aussieht?

Die häufigste Ursache ist, dass CODEOWNERS vom Base-Branch des PRs gelesen wird – eine Datei, die nur auf Ihrem Feature-Branch vorhanden ist, wird daher nie ausgelöst. Weitere stille Ursachen sind: ein Eigentümer ohne Schreibzugriff, ein Team-Eigentümer, der nicht sichtbar ist oder keinen Schreibzugriff hat, ein leeres Team, ein Draft-PR (der nie Code-Owner-Anfragen auslöst), eine Datei über 3 MB, Pfade mit falscher Groß-/Kleinschreibung oder eine ungültige Zeile, die GitHub ohne Warnung überspringt.

Blockiert CODEOWNERS Merges von sich aus, oder benötige ich Branch-Protection?

CODEOWNERS allein fordert nur Reviewer an und blockiert niemals einen Merge. Um Merges zu sperren, müssen Sie zusätzlich zwei Einstellungen gemeinsam aktivieren: 'Require a pull request before merging' und 'Require review from Code Owners'. Konfigurieren Sie diese in einem Ruleset unter Settings, Rules, Rulesets oder in einer klassischen Branch-Protection-Regel unter Settings, Branches. Beide Wege sind verfügbar, wobei Rulesets der neuere Ansatz ist.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — self-hosted, with full data ownership.

Star on GitHub

We use cookies to improve your experience. By using our site, you accept cookies.