+190 XP

Codex auf GitHub: PR-Reviews und Actions

# Codex auf GitHub: PR-Reviews und Actions

Codex kann Pull Requests reviewen und innerhalb von GitHub Actions laufen, sodass jeder Diff eine automatisierte Durchsicht bekommt, bevor ihn ein Mensch überhaupt öffnet. Damit wird Codex von einem Werkzeug, das Sie manuell aufrufen, zu einem Teil Ihrer Pipeline: ein Reviewer, der Stil kommentiert, offensichtliche Bugs findet, riskante Änderungen markiert und bei einem Deploy um 23 Uhr am Freitag nie müde wird.

Diese Lektion setzt das konkret um. Sie sehen die zwei Wege, über die Codex an GitHub angebunden wird, einen saubereren Workflow, der jeden PR reviewt, die genau benötigten Token-Berechtigungen und wie Sie verhindern, dass Ihr Budget leise ausblutet.

Zwei Wege, wie Codex auf Ihr Repo trifft

Es gibt zwei unterschiedliche Integrationspfade, und deren Verwechslung verursacht die meiste Verwirrung.

Die Codex GitHub App (managed). Sie installieren Codex von der ChatGPT-Seite aus und verbinden Ihren GitHub-Account. Codex kann dann direkt im GitHub-UI Issues und Pull Requests zugewiesen werden. Sie erwähnen Codex, es liest den PR und kann Änderungen vorschlagen oder Review-Kommentare hinterlassen. Das ist der Weg mit geringem Aufwand: kein YAML, kein Runner, OpenAI hostet die Ausführung.

Codex CLI innerhalb von GitHub Actions (selbst gesteuert). Sie führen die Codex CLI als Step in Ihrem eigenen Workflow aus. Das wollen Sie, wenn Sie Kontrolle brauchen: eigene Prompts, eigene Secrets, Gating auf bestimmte Dateipfade und Output, der in andere Steps weiterfließt. Runner und Logik gehören Ihnen.

Die managed App ist schneller eingeführt. Der Actions-Weg ist das, was ein ernsthaftes Team ausliefert, weil Sie die Review-Logik im Repo selbst versionieren und genau nachvollziehen können, was läuft. Der Rest dieser Lektion konzentriert sich auf den Actions-Weg.

Was "den Diff reviewen" tatsächlich bedeutet

Ein Pull Request ist ein Diff plus Kontext. Wenn Codex einen PR in Actions reviewt, sieht das nützliche Muster so aus:

1. Der Workflow triggert auf pull_request.

2. Ein Step berechnet den Diff (die geänderten Zeilen, nicht das ganze Repo).

3. Codex liest den Diff mit einem Review-Prompt.

4. Codex postet einen Kommentar zurück auf den PR über die GitHub API.

Die entscheidende Design-Entscheidung ist, was Sie dem Modell geben. Werfen Sie nicht bei jedem PR das komplette Repository in den Kontext. Das ist langsam, teuer und größtenteils Rauschen. Geben Sie den Diff, und vielleicht die Dateien, die der Diff berührt. Das Signal liegt in dem, was sich geändert hat.

Ein sauberer Workflow, der jeden PR reviewt

Hier ein minimaler, lauffähiger Workflow. Er läuft bei jedem PR, sendet den Diff mit einem fokussierten Review-Prompt an Codex und postet das Ergebnis als einen einzigen Kommentar.

yaml
name: Codex PR Review
on:
  pull_request:
    types: [opened, synchronize]

permissions:
  contents: read
  pull-requests: write

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Compute diff
        run: |
          git diff origin/${{ github.base_ref }}...HEAD > pr.diff
          echo "Diff size: $(wc -l < pr.diff) lines"

      - name: Review with Codex
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
        run: |
          npm install -g @openai/codex
          codex exec --skip-git-repo-check \
            "Review the changes in pr.diff. Flag bugs, security \
             issues, and missing tests. Be concise. If it looks \
             good, say so in one line." > review.md

      - name: Post comment
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: gh pr comment ${{ github.event.pull_request.number }} --body-file review.md

Ein paar Dinge sind hier beachtenswert.

fetch-depth: 0 holt die vollständige Historie, damit der git diff gegen den Base-Branch tatsächlich funktioniert. Ohne das bekommen Sie einen Shallow Clone und der Diff bricht.

codex exec führt Codex nicht-interaktiv aus, genau das, was Sie in CI wollen. Es liest den Prompt, macht die Arbeit und beendet sich. Das Flag --skip-git-repo-check verhindert Beschwerden über den Checkout-Zustand des Runners.

Der letzte Step nutzt gh, die GitHub CLI, die auf GitHub-gehosteten Runnern vorinstalliert ist. gh pr comment postet das Review. Kein eigener API-Kleber nötig.

Token-Berechtigungen, präzise

Zwei verschiedene Tokens sind im Spiel, und sie gleich zu behandeln ist ein Sicherheitsfehler.

`GITHUB_TOKEN` ist das Token, das GitHub automatisch für den Workflow-Run erzeugt. Es wird durch den permissions:-Block am Anfang der Datei eingeschränkt. Der Block oben gewährt:

  • contents: read, damit der Checkout Ihren Code lesen kann.
  • pull-requests: write, damit gh pr comment posten kann.

Das ist der gesamte Fußabdruck. Beachten Sie, was fehlt: kein contents: write, kein actions: write, nichts, was dem Job erlaubt, Code zu pushen oder das Repo umzuschreiben. Gewähren Sie den engsten Satz, mit dem der Job funktioniert. Wenn Ihr Workflow nur kommentiert, braucht er nie Schreibzugriff auf Code. GitHubs Dokumentation zu Berechtigungen listet jeden Scope auf.

`OPENAI_API_KEY` ist Ihr Key für die OpenAI API, gespeichert als Repository- oder Organisations-Secret. Er autorisiert die Codex-Calls und ist das, worüber abgerechnet wird. Mit GitHub-Berechtigungen hat er nichts zu tun; er ist das Credential auf Modellseite.

Halten Sie die beiden im Kopf getrennt: GITHUB_TOKEN steuert, was der Job *mit Ihrem Repo* tun kann, OPENAI_API_KEY steuert, was er *mit OpenAI* tun kann (und was das kostet).

Sicher bleiben

Die gefährliche Variante dieses Musters läuft auf pull_request_target mit Write-Berechtigungen und führt dann Code aus dem PR aus. Diese Kombination erlaubt einem bösartigen Fork, beliebige Befehle mit Ihren Secrets auszuführen. Tun Sie das nicht.

Der Workflow oben nutzt pull_request, nicht pull_request_target. Beim Standard-Trigger pull_request laufen Workflows aus Forks mit einem read-only GITHUB_TOKEN und ohne Zugriff auf Ihre Secrets, womit der Codex-Step für externe Beitragende übersprungen wird. Das ist der sichere Standard. Bei internen PRs aus Branches in Ihrem eigenen Repo sind die Secrets verfügbar und das Review läuft normal.

Drei weitere Leitplanken:

  • Lassen Sie den Reviewer niemals PR-Code ausführen. Einen Diff als Text zu reviewen ist sicher. Die Build-Skripte oder Tests des Branches mit Ihrem OPENAI_API_KEY in der Umgebung auszuführen, ist der Weg, auf dem Supply-Chain-Angriffe passieren. Halten Sie Review und Ausführung getrennt.
  • Pinnen Sie Ihre Actions. actions/checkout@v4 ist als Tag in Ordnung, aber bei allem von Dritten pinnen Sie auf einen vollständigen Commit-SHA, damit ein kompromittierter Tag keinen Code einschleusen kann.
  • Speichern Sie den Key auf Org-Ebene mit Environment Protection, wenn mehrere Repos ihn teilen, damit Sie an einer Stelle rotieren.

Securing GitHub Actions Workflows

Watch on YouTube

Günstig bleiben

Jeder PR, der diesen Workflow triggert, macht einen API-Call, und große Diffs bedeuten hohe Token-Zahlen. Ein Repo mit starkem PR-Verkehr kann echte Kosten verursachen, wenn Sie unachtsam sind. Kontrollieren Sie das auf drei Ebenen.

Filtern, was triggert. Laufen Sie nur auf den Branches und Pfaden, die zählen. Überspringen Sie reine Doku- oder generierte Dateiänderungen:

yaml
on:
  pull_request:
    types: [opened, synchronize]
    paths:
      - "src/**"
      - "!**/*.md"

Jetzt verbraucht ein PR, der nur Markdown berührt, nie ein Token.

Begrenzen Sie den Diff, den Sie senden. Ein Refactoring über 4.000 Zeilen braucht keinen Review-Kommentar mit vollem Kontext; der Diff selbst ist das Rauschen. Kürzen oder verwerfen Sie übergroße Diffs, bevor das Modell sie sieht:

bash
if [ "$(wc -l < pr.diff)" -gt 800 ]; then
  echo "Diff too large for automated review; skipping." > review.md
  exit 0
fi

Entprellen Sie `synchronize`. Das synchronize-Event feuert bei jedem Push auf den PR-Branch. Wenn jemand zehn Commits in einer Minute pusht, bekommen Sie zehn Reviews. Nutzen Sie concurrency, um überholte Runs abzubrechen, damit nur der letzte Push reviewt wird:

yaml
concurrency:
  group: codex-review-${{ github.event.pull_request.number }}
  cancel-in-progress: true

Dieser einzelne Block senkt die Ausgaben bei aktiven PRs oft um mehr als die Hälfte, weil Sie nicht mehr für Reviews von Code zahlen, der Sekunden später ersetzt wurde.

Wissenscheck

1. Was ist der wesentliche Nutzen davon, Codex Pull Requests innerhalb von GitHub Actions reviewen zu lassen?

2. Warum empfiehlt die Lektion, Codex den Diff (und eventuell die davon berührten Dateien) zu geben statt bei jedem PR das gesamte Repository?

3. Warum würde ein ernsthaftes Team laut Lektion die Codex CLI in GitHub Actions der managed GitHub App vorziehen?

MEHRFACHAUSWAHL

4. Wählen Sie ALLE Aussagen, die den Weg über die managed Codex GitHub App korrekt beschreiben.

Wählen Sie alle richtigen Antworten aus.

MEHRFACHAUSWAHL

5. Wählen Sie ALLE Schritte, die dem in der Lektion beschriebenen nützlichen Muster für das Reviewen eines PR in GitHub Actions entsprechen.

Wählen Sie alle richtigen Antworten aus.

Über einen einzelnen Kommentar hinaus

Ein einfacher Kommentar ist der Startpunkt. Sobald die Verkabelung steht, geht es bei den interessanten Schritten darum, *wohin der Output geht* und *wie strukturiert er ist*.

Inline-Review-Kommentare. Statt eines Kommentars am PR können Sie über die GitHub Review API Kommentare an bestimmten Zeilen posten. Das erfordert, Codex' Funde auf Dateipfade und Zeilennummern zurückzuführen, und genau hier zahlen sich structured outputs aus: lassen Sie das Modell JSON mit den Feldern path, line und comment zurückgeben, iterieren Sie darüber und posten Sie jeden Eintrag mit gh api. Structured outputs haben Sie im API-Block schon kennengelernt; hier ist eine saubere Anwendung, denn "hinterlasse einen Kommentar an Zeile 42 von auth.py" ist nur dann umsetzbar, wenn das Modell Ihnen die Zeilennummer in parsebarer Form liefert.

Gating des Merges. Ein Review-Kommentar ist beratend. Wenn Sie Zähne wollen, lassen Sie den Job mit Exit-Code ungleich null enden, wenn Codex etwas Kritisches markiert, und machen Sie den Check im Branch Protection verpflichtend. Seien Sie hier konservativ: ein Reviewer, der Merges wegen Stil-Kleinigkeiten blockiert, wird innerhalb einer Woche abgeschaltet. Blockieren Sie nur bei den Kategorien, die Sie wirklich interessieren, etwa ein geleaktes Secret-Muster oder ein entfernter Test.

Reicheren Kontext selektiv zuführen. Bei einem PR, der ein einzelnes Modul berührt, gibt der vollständige Quellcode dieses Moduls (nicht des ganzen Repos) Codex genug Kontext, um "du hast die Funktionssignatur geändert, aber nicht ihre Aufrufer" zu erkennen. Die Regel bleibt: erweitern Sie den Kontext bewusst, entsprechend den geänderten Dateien, niemals pauschal.

Wann Sie stattdessen die managed App nutzen sollten

Wenn Ihr Team klein ist und Sie vor allem eine kompetente zweite Meinung zu PRs wollen, ohne YAML zu pflegen, ist die managed Codex GitHub App die bessere Wahl. Sie weisen Codex einem PR zu, und es reviewt. Sie verlieren die feine Kontrolle über Prompts, Gating und Kostenfilter, gewinnen aber Einfachheit, und OpenAI kümmert sich um den Runner.

Greifen Sie zum Actions-Weg, wenn Sie eines davon brauchen: eigene, im Repo versionierte Review-Kriterien, Integration mit anderen CI-Steps, strikte Kostenkontrolle oder streng getrennte Handhabung, welche Secrets welche Jobs berühren. Die meisten Teams starten mit der App und wechseln zu Actions, wenn die Review-Logik etwas wird, das sie besitzen und tunen wollen.

Wichtigste Erkenntnisse

  • Nutzen Sie den `pull_request`-Trigger, nicht `pull_request_target`, damit PRs aus Forks ohne Ihre Secrets laufen. Führen Sie niemals PR-Code in einem Job aus, der Ihren OPENAI_API_KEY hält.
  • Beschränken Sie `GITHUB_TOKEN` auf das Minimum: contents: read und pull-requests: write genügen, um zu reviewen und zu kommentieren. Halten Sie es gedanklich getrennt von OPENAI_API_KEY, der die Kosten steuert.
  • Senden Sie den Diff, nicht das Repo. Filtern Sie Trigger nach Pfad, begrenzen Sie übergroße Diffs vor dem API-Call und fügen Sie einen concurrency-Block hinzu, um überholte Runs bei schnellen Pushes abzubrechen.
  • Nutzen Sie structured outputs (JSON mit Pfad und Zeile), wenn Sie Inline-Review-Kommentare statt eines zusammengefassten Blocks wollen.
  • Starten Sie mit der managed Codex App; wechseln Sie zu Actions, wenn Sie versionierte Review-Logik, Merge-Gating oder strenge Kostenkontrolle brauchen.

Was Sie aus dieser Lektion umsetzen

Diese Maßnahmen sind im Playbook der Rolle zusammengefasst.

  • PR-Review-Actions mit pull_request auslösen, nie mit pull_request_target
Vollständiges Action Playbook ansehen