# GitHub-Release-Automatisierung mit KI-Agenten und Freigabe

Release-Automatisierung sollte Büroarbeit abnehmen, einem Coding-Agenten aber nicht die Befugnis geben, Software nach eigenem Ermessen zu verteilen. Ein Agent kann Änderungen sammeln, eine Version berechnen, einen Release-Kandidaten bauen, Notizen entwerfen und Artefakte zusammenstellen. Veröffentlichung und Rollback brauchen eine Person, die eine konkrete Release-Anfrage prüft und genau diese Aktion bestätigt.

Diese Grenze klingt konservativ, bis du ein Release bereinigen musst, das die falsche Binärdatei, einen verschobenen Tag oder Notizen enthielt, die einen nie ausgelieferten Fix versprachen. Der API-Aufruf ist einfach. Die Folgen rückgängig zu machen, ist es meist nicht.

## Gib dem Agenten eine Release-Werkbank, nicht die Kontrolle über das Repository

Ein Release-Agent sollte über eine kleine, klar definierte Menge an Aktionen verfügen, die genau zu seiner Aufgabe passt. Ein weitreichender Schreibzugriff auf das Repository wirkt bequem, weil dadurch keine Schnittstelle entworfen werden muss. Gleichzeitig kann eine falsche Anweisung eine Release-Aufgabe in das Löschen von Tags, Änderungen an Branches, Workflow-Anpassungen oder eine öffentliche Ankündigung verwandeln.

Bei der GitHub-Release-Automatisierung trenne ich Vorbereitung und Verteilung. Der Agent darf Repository-Metadaten lesen, Commits in einem freigegebenen Bereich prüfen, den Build ausführen, Artefakt-Hashes berechnen, ein Draft-Release erstellen oder aktualisieren und Artefakte in diesen Entwurf hochladen. Er darf kein Release veröffentlichen, kein Release löschen, keinen Tag ändern, keine Repository-Einstellungen bearbeiten, keine Tokens erstellen und keinen beliebigen GitHub-Endpunkt aufrufen.

Formuliere die erlaubten Aktionen als Verben mit festen Eingaben. Das ist nützlicher, als einem Agenten zu sagen, er solle «vorsichtig sein».

- `inspect_release_range(base_tag, head_sha)` gibt Commits und Pull Requests zurück
- `build_candidate(head_sha)` gibt Artefakte und SHA-256-Digests zurück
- `create_draft(version, target_sha, notes)` gibt eine Draft-ID zurück
- `upload_asset(draft_id, filename, digest)` lädt eine geprüfte Datei hoch
- `request_publish(draft_id)` erstellt eine Bestätigungsanfrage

Das letzte Verb ist entscheidend. `request_publish` darf nicht stillschweigend veröffentlichen, wenn niemand antwortet. Es sollte einen ausstehenden Status zurückgeben, den der Aufrufer anzeigen und abfragen kann. Ein Release-Workflow, der eine Zeitüberschreitung als Zustimmung behandelt, hat seine eigene Kontrolle bereits ausgehebelt.

Vermeide einen Ausweg wie `github_api(method, path, body)`. Teams fügen ihn für die eine ungewöhnliche Aktion hinzu, die nicht in den ersten Entwurf passte. Der Agent wird ihn irgendwann verwenden, weil Sprachmodelle den kürzesten Weg durch eine Schnittstelle bevorzugen. Jeder uneingeschränkte Request-Method erzeugt aus deiner eng begrenzten Berechtigung wieder ein allgemeines Repository-Token.

Dasselbe gilt für den Shell-Zugriff. Stelle nicht `gh` mit beliebigen Argumenten bereit und nenne das eine Release-Schnittstelle. Kapsle die konkreten erlaubten Aktionen, validiere ihre Argumente und lehne alles andere ab. Wenn du nächsten Monat eine neue Aktion brauchst, füge sie bewusst hinzu, teste sie und entscheide, wo eine Bestätigung erforderlich ist.

## Ein Draft-Release ist ein Prüfobjekt, kein veröffentlichtes Release

Ein GitHub-Draft-Release ermöglicht es, den öffentlichen Datensatz zusammenzustellen, ohne ihn öffentlich zu machen. Die prüfende Person erhält dadurch etwas Konkretes: Version, Ziel-Commit, generierte Notizen, angehängte Dateien, Prüfsummen und den Pre-Release-Status. Die Meldung «Bereit zur Veröffentlichung von v2.4.0» ist kein ausreichender Nachweis.

GitHub unterscheidet in seiner REST-Dokumentation zwischen dem Erstellen eines Releases mit `draft: true` und seiner Veröffentlichung durch eine Änderung des Draft-Status. GitHub dokumentiert außerdem, dass `make_latest` beeinflusst, welches Release als neuestes angezeigt wird. Diese Felder sehen wie gewöhnliche Metadaten aus, wirken sich aber auf Nutzer und Tools aus. Behandle sie als Veröffentlichungsentscheidungen und nicht als Standardwerte, die ein Agent erraten soll.

Eine solide Anfrage enthält unveränderliche Kennungen. Die Versionsnummer ist für Menschen nützlich, der Commit-SHA identifiziert jedoch den tatsächlich geprüften Quellstand. Der Artefakt-Digest identifiziert die Datei, die tatsächlich gebaut wurde. Wenn die Anfrage nur «v2.4.0 veröffentlichen» lautet, muss die prüfende Person das Release rekonstruieren, während ein ungeduldiger Agent wartet.

Verwende ein strukturiertes Freigabeprotokoll wie dieses:

```json
{
  "operation": "publish_release",
  "repository": "acme/widgets",
  "draft_id": "123456",
  "version": "v2.4.0",
  "target_sha": "8b0c5f7c2d6c4e1a9f1a3b0e5e92d7a4c6f80c11",
  "prerelease": false,
  "make_latest": "true",
  "assets": [
    {"name": "widgets-v2.4.0.tar.gz", "sha256": "b3e1..."},
    {"name": "widgets-v2.4.0.tar.gz.sha256", "sha256": "f18a..."}
  ],
  "notes_digest": "c921..."
}
```

Die bestätigende Person sollte den Entwurf öffnen und dieses Protokoll mit dem Zustand des Repositorys vergleichen. Der Digest der Notizen klingt vielleicht übertrieben, bis jemand einen Entwurf nach der Prüfung bearbeitet. Nicht jedes Komma muss unveränderlich sein. Du musst aber erkennen können, ob sich Artefaktliste, Ziel oder Release-Klassifizierung geändert haben.

Ein Entwurf ist nicht automatisch harmlos. Er kann für Nutzer mit Repository-Zugriff sichtbar sein und interne Tools auslösen. Ordne das Erstellen eines Entwurfs nur dann der Gruppe mit geringerem Risiko zu, wenn deine Umgebung ihn tatsächlich als Prüfmaterial behandelt. Wenn Entwurfsartefakte in eine Paketregistrierung oder einen Artefaktspiegel fließen, muss auch der Upload bestätigt werden.

## Binde die Version an einen Commit und die Artefakte an die Version

Der häufigste Release-Fehler ist kein böswilliger Agent. Es ist ein Release, dessen Version, Tag, Quell-Commit und Binärdatei aus unterschiedlichen Momenten eines sich verändernden Repositorys stammen.

Ein sauberer Prozess wählt zuerst einen unveränderlichen Commit-SHA. Der Build läuft aus diesem SHA und nicht aus einem Branch-Namen. Nach Abschluss des Builds zeichnet der Agent die Digests auf. Erst dann erstellt er einen Tag und einen Entwurf, die beide auf denselben SHA zeigen. Wenn dein Release-Prozess einen signierten Tag verlangt, sollte die Signieridentität außerhalb des Agent-Prozesses arbeiten, genau wie das Publishing-Credential.

Lass den Agenten keine veränderliche Referenz wie `main` als Ziel eines öffentlichen Releases verwenden. Ein Build kann bei einer Revision starten, während ein weiterer Merge den Branch vor dem Erstellen des Releases weiterbewegt. GitHub hängt ein Release problemlos an das spätere Ziel, wenn dein Code zu diesem Zeitpunkt `main` auflösen lässt. Dann können sich die Notizen auf eine Revision und das Artefakt auf eine andere beziehen.

Prüfe die Beziehung vor der Bestätigungsabfrage. Eine einfache lokale Prüfung kann frühzeitig abbrechen:

```sh
git fetch --tags origin
git rev-parse "v2.4.0^{}"
git rev-parse HEAD
shasum -a 256 dist/widgets-v2.4.0.tar.gz
```

Die ersten beiden Objekt-IDs müssen nach dem Erstellen des Tags übereinstimmen. `HEAD` muss der geprüfte SHA sein, wenn du in diesem Checkout gebaut hast. Der Prüfsummenbefehl erzeugt eine Zeile wie diese:

```text
b3e1f2...  dist/widgets-v2.4.0.tar.gz
```

Übernimm genau diesen Digest in das Freigabeprotokoll. Bitte die prüfende Person nicht, einem Dateinamen zu vertrauen. Eine Datei namens `widgets-v2.4.0.tar.gz` kann einen Debug-Build, einen alten Build oder eine Binärdatei für eine andere Architektur enthalten.

Die Dokumentation zu GitHub Actions warnt davor, dass `pull_request_target` im Kontext des Basis-Repositorys läuft und bei unvorsichtiger Verwendung Schreibberechtigungen oder Geheimnisse für nicht vertrauenswürdigen Code aus Pull Requests zugänglich machen kann. Dasselbe gilt für einen Release-Agenten: Baue kein verteilbares Artefakt aus nicht vertrauenswürdigem Code in einem Job, der veröffentlichen kann. Trenne die Validierung nicht vertrauenswürdiger Änderungen von dem kontrollierten Build, der Release-Berechtigungen erhält.

Auch die Versionsberechnung braucht eine feste Regel. Ein Agent kann anhand von Conventional Commits oder zusammengeführten Labels eine Version vorschlagen, aber ein Vorschlag ist kein Nachweis. Eine verantwortliche Person sollte festlegen, wie Breaking Changes, zurückgesetzte Änderungen und Release-Branches die Versionierung beeinflussen. Automatische semantische Versionierung versagt unauffällig, wenn im Repository keine einheitliche Disziplin bei Commit-Nachrichten herrscht.

## Generierte Release-Notizen brauchen eine menschliche Redaktion

Ein Agent kann aus zusammengeführten Pull Requests einen überzeugenden ersten Entwurf erstellen. Er weiß jedoch nicht, ob eine Migration eine Warnung verdient, ob ein Beitragender namentlich genannt werden möchte oder ob eine Verhaltensänderung einen Anwendungsfall beeinträchtigt, der in keinem Commit-Titel auftauchte.

Lass ihn Notizen in Abschnitten erstellen, die Unsicherheiten sichtbar machen. Stelle nutzerrelevante Änderungen an den Anfang, danach Fehlerbehebungen und anschließend interne Arbeiten. Füge Verweise auf Pull Requests und den verwendeten Commit-Bereich ein. Markiere Aussagen, die aus einer Codeprüfung und nicht aus der Beschreibung einer verantwortlichen Person stammen. So kann ein flüssiger Absatz keine Vermutung verbergen.

Ich lehne die verbreitete Anweisung «Schreibe aus dem Git-Log ausgefeilte Release-Notizen» ab. Sie ist beliebt, weil sofort ein Dokument entsteht. Sie ist falsch, weil Commit-Nachrichten die Umsetzungsabsicht beschreiben, nicht unbedingt das ausgelieferte Verhalten. Ein Commit namens «fix auth» kann eine Test-Fixture reparieren, eine Fehlermeldung ändern oder einen schwerwiegenden Fehler schließen. Die Release-Notiz muss die tatsächlichen Auswirkungen für Nutzer beschreiben.

Vor der Veröffentlichung sollte die prüfende Person einige einfache Fragen beantworten:

- Enthält der Ziel-Commit jede hier behauptete Änderung?
- Ist ein entfernter oder zurückgesetzter Pull Request im Bereich geblieben?
- Müssen Nutzer Konfiguration, Daten, Berechtigungen oder Clients ändern?
- Muss ein Sicherheitstext von den Personen geprüft werden, die den Vorfall untersucht haben?
- Ist dies ein Pre-Release, und soll GitHub es als neuestes Release anzeigen?

Gib dem Agenten keine Sicherheitswarnung mit der Bitte, sie für ein öffentliches Release umzuschreiben. Die prüfende Person muss Zeitpunkt der Veröffentlichung, betroffene Versionen, Workarounds und Danksagungen festlegen. Ein Agent darf bestätigte Formulierungen formatieren, aber nicht entscheiden, was öffentlich wird.

Halte Release-Notizen und Release-Artefakte zum Zeitpunkt der Prüfung zusammen. Wenn eine prüfende Person «fügt ARM-Unterstützung hinzu» liest, sollte sie das ARM-Artefakt im Entwurf und seine Prüfsumme in der Freigabeanfrage sehen. So wird eine Reihe peinlicher Fehler erkannt, die getrennte Prüfungen von Dokumentation und Build übersehen.

## Die Bestätigung muss an der nicht umkehrbaren Grenze erfolgen

Ein Bestätigungsdialog, der erst nach der Veröffentlichung erscheint, dokumentiert nur das Bedauern. Zeige die Abfrage unmittelbar vor der Aktion, die den Verteilungsstatus ändert, und stelle die exakt zu bestätigende Anfrage dar.

Die bestätigende Person braucht genug Kontext, um innerhalb weniger Sekunden eine Abweichung zu erkennen: Repository, Titel des Entwurfs, Ziel-SHA, Namen und Digests der Artefakte, Pre-Release-Status, Auswahl des neuesten Releases und der Prozess, der die Bestätigung anfordert. Verstecke das Repository nicht in einem eingeklappten Detailbereich. Ein Release für das falsche Repository kann schädlicher sein als eine fehlerhafte Notiz.

Verwende für diese Aktionen jeweils eine eigene Bestätigung:

- ein Draft-Release veröffentlichen
- ein Release löschen oder die Veröffentlichung rückgängig machen
- einen Release-Tag löschen
- ein vorhandenes Release-Artefakt ersetzen
- ein Release von Pre-Release auf stabil ändern oder als neuestes markieren

Die Liste ist absichtlich kurz. Wer für jeden Lesezugriff und jede Artefakt-Prüfsumme um Erlaubnis bitten muss, gewöhnt sich daran, ohne hinzusehen zu bestätigen. Eine Entscheidung an einer öffentlichen oder destruktiven Grenze erhält die Aufmerksamkeit dort, wo sie etwas bewirken kann.

Die Bestätigung sollte an einen Anfrage-Digest gebunden sein. Wenn der Agent den Entwurf ändert, ein Artefakt hinzufügt oder `make_latest` ändert, muss die Bestätigung ungültig werden und erneut angefordert werden. Verwende keinen früheren Klick wieder, nur weil die Versionsnummer noch übereinstimmt.

Sallyports sitzungsbezogene Autorisierung kann einen neuen Agent-Prozess erkennen, bevor er eine Aktion ausführt. Die Steuerung pro Aufruf kann eine separate Bestätigung für die Nutzung eines bestimmten Credentials verlangen. Das passt gut zu Release-Arbeiten: Ein geprüfter Agent-Lauf darf einen Entwurf vorbereiten, aber bei der Nutzung des Publishing-Credentials ist eine Entscheidung pro Aufruf erforderlich.

Verwechsle eine Bestätigung nicht mit Authentifizierung. Eine Code-Signing-Identität oder eine CI-Workload-Identität zeigt, welcher Prozess die Anfrage gestellt hat. Die Bestätigung sagt, dass eine Person genau diese nach außen gerichtete Aktion akzeptiert hat. Wenn ein Release schiefgeht, brauchst du beide Nachweise.

## Halte Credentials aus Prompt und Umgebung des Agenten heraus

Ein Agent, der direkt über ein GitHub-Token verfügt, kann deine sorgfältig entworfene Bestätigungsschnittstelle mit einem curl-Aufruf, einer geänderten Workflow-Datei oder einem nicht ausreichend eingeschränkten Tool-Aufruf umgehen. Prompt-Anweisungen können diese Lücke nicht schließen.

Bewahre das Credential in einer Komponente auf, die nur erlaubte Aktionen ausführt. Der Agent übermittelt eine strukturierte Anfrage. Die Komponente validiert Repository, Verb, Zielreferenz und Artefaktregeln, holt die erforderliche Bestätigung ein, fügt das Credential in den ausgehenden Aufruf ein und gibt das Ergebnis zurück. Der Agent erhält das Geheimnis nie, auch nicht als redigierten Platzhalter.

Sallyport bewahrt API- und SSH-Geheimnisse in seinem verschlüsselten Tresor auf und führt die HTTP- oder SSH-Aktion selbst aus. Ein MCP-fähiger Agent muss das Credential daher nicht besitzen. Die Tresorsperre lehnt Aktionen ab. Das ist bei einem unbeaufsichtigten Rechner der gewünschte Zustand und verhindert, dass ein Token in der Shell-Umgebung liegen bleibt.

Verwende ein eigenes Credential für Releases. Beschränke es auf die Repositories, in denen es gebraucht wird, und entferne die Berechtigung zur Verwaltung von Organisationen, Webhooks und Actions-Einstellungen sowie zum Schreiben in andere Repositories. GitHub Apps passen oft besser als das persönliche Token eines Menschen, weil Installation und Berechtigungen einen engeren Zweck haben. Die genaue Wahl hängt von deiner Repository-Struktur ab, aber ein gemeinsam genutztes Maintainer-Token ist eine schlechte Release-Identität.

Füge einen Token nicht in eine Agent-Anweisung, eine `.env`-Datei oder ein CI-Artefakt ein. Redigieren löst das Problem nicht. Sobald ein Prozess ein Geheimnis lesen kann, kann er es oft in einem Ausgabefeld, einem Release-Text, einem Dateinamen oder einer Anfrage an einen anderen Dienst verstecken. Vorbeugung beginnt damit, das Geheimnis diesem Prozess gar nicht erst zu übergeben.

## Rollback ist eine korrigierende Release-Entscheidung, kein Löschknopf

Das Löschen eines GitHub-Releases kann eine Seite entfernen, ruft aber keine heruntergeladenen Archive, gecachten Metadaten, geklonten Tags, gespiegelten Quellen oder bereits ausgelösten nachgelagerten Deployments zurück. Ein Release-Agent, der Löschen als sauberes Rückgängigmachen behandelt, erschwert die Untersuchung eines Vorfalls.

Beginne eine Rollback-Anfrage mit der Klassifizierung des Fehlers. Ist das Artefakt fehlerhaft, aber ungefährlich, veröffentliche ein korrigiertes Release mit einer klaren Notiz und entscheide, ob das frühere Release als Pre-Release markiert oder aus der Position des neuesten Releases entfernt werden soll. Enthält das Artefakt ein Geheimnis, Schadcode oder eine schwerwiegende Sicherheitslücke, stoppe zuerst die Verteilung, widerrufe betroffene Credentials, informiere Nutzer über deine bestehenden Kanäle und bewahre die für die Untersuchung nötigen Beweise auf.

Eine Person sollte Rollback-Aktionen getrennt von der Veröffentlichung bestätigen, weil die Folgen unterschiedlich sind. Die Abfrage muss angeben, was sich ändert und was sichtbar bleibt. «Release v2.4.0 löschen» ist schwach. «Öffentlichen Release-Eintrag und Artefakte für v2.4.0 löschen; Tag v2.4.0 bleibt auf SHA X; bestehende Downloads können nicht zurückgerufen werden» zeigt, was tatsächlich autorisiert wird.

Lass einen Agenten keinen Tag löschen, nur damit seine Release-Notizen ordentlich aussehen. Tags sind Referenzen, von denen andere Builds und Nutzer abhängig sein können. Wenn du einen Tag ersetzen musst, bewahre den alten SHA im Vorfallsprotokoll auf und kommuniziere die Änderung. Das Verschieben eines veröffentlichten Versions-Tags erschwert spätere Prüfungen erheblich.

Die sicherere Standardeinstellung ist eine korrigierende Version. Sie schafft einen sauberen Audit-Pfad, lässt nachgelagerte Tools das korrigierte Artefakt erkennen und tut nicht so, als hätte das erste Release nie stattgefunden. Löschen kann für eine versehentliche Veröffentlichung sinnvoll sein, bevor sie jemand vernünftigerweise konsumieren konnte. Das ist jedoch eine operative Entscheidung und keine automatische Bereinigungsaufgabe.

## Ein Audit-Protokoll muss die Aktion rekonstruieren, nicht die Geschichte darum herum

Wenn jemand fragt, wer eine Version veröffentlicht hat, ist «der Agent war es» keine Antwort. Du musst den Agent-Prozess, die Person, die die Aktion bestätigt hat, die Credential-Instanz, die sie ausgeführt hat, die Anfragewerte und die Antwort von GitHub identifizieren.

Zeichne ein Ereignis für die Agent-Sitzung und ein weiteres für jede Release-Aktion auf. Das Sitzungsprotokoll beantwortet, wer den Lauf gestartet hat und wann er seine Berechtigung verloren hat. Das Aktionsprotokoll zeigt, welche endpunktähnliche Aktion mit welchen aufgelösten Werten ausgeführt wurde. Halte Geheimnisse aus beiden Protokollen heraus.

Bei einer Veröffentlichung solltest du mindestens Repository, Draft-ID, Release-ID, Version, Ziel-SHA, vom Agenten gelieferte Quellreferenz, Namen und Digests der Artefakte, Release-Flags, Notiz-Digest, Entscheidungszeitpunkt, bestätigende Identität, Prozessidentität, Ergebniscodes und Antwortkennung erfassen. Zeichne auch Fehler auf. Eine abgelehnte Anfrage ist ein Nachweis dafür, dass eine Grenze funktioniert hat.

Sallyport stellt Sitzungs- und Aktivitätsjournale aus einem schreibgeschützten, verschlüsselten und hashverketteten Audit-Log bereit. Der Befehl `sp audit verify` prüft die Kette offline über den Ciphertext, ohne ein Tresorgeheimnis zu benötigen. Diese Eigenschaft ist für Release-Nachweise nützlich, weil ein Auditor prüfen kann, ob Datensätze verändert wurden, ohne Credential-Material zu erhalten.

Protokolle ersetzen keine Kontrollen. Ein perfektes Log, das die Veröffentlichung des falschen Pakets durch einen Agenten dokumentiert, liefert dir eine saubere Nachbesprechung und ein fehlerhaftes Release. Das Protokoll verdient seinen Platz, wenn du es mit engen Aktionen, festen Kennungen und einer Bestätigung verbindest, die eine geänderte Anfrage nicht überlebt.

## Ein Release-Gate sollte bei abweichenden Fakten sicher stoppen

Das Release-Gate sollte Unklarheiten ablehnen, statt von der bestätigenden Person zu verlangen, sie auszugleichen. Wenn das Ziel des Entwurfs vom geprüften SHA abweicht, ein Artefakt-Digest nicht mit dem Build-Manifest übereinstimmt, der Entwurf nicht mehr existiert oder sich die Release-Anfrage seit der Bestätigung geändert hat, muss der Prozess stoppen und eine neue Anfrage erstellen.

Während eines hektischen Releases kann dieses Verhalten kleinlich wirken. Es ist günstiger, als später klären zu müssen, ob sich ein Tag zwischen Build und Veröffentlichung verschoben hat oder ob ein Agent nach der Prüfung eine neu gebaute Datei hochgeladen hat. Release-Arbeit profitiert an genau dieser Stelle von etwas Reibung.

Teste das Gate mit absichtlichen Fehlerfällen, bevor du ihm ein stabiles Release anvertraust. Bitte den Agenten, einen Entwurf mit einem abweichenden SHA zu veröffentlichen. Lade ein Artefakt hoch, dessen Bytes sich nach der Prüfsummenberechnung ändern. Ändere den Titel eines Entwurfs nach der Bestätigung. Versuche, über die Vorbereitungsschnittstelle ein Release zu löschen. Jeder Versuch sollte mit einem konkreten Protokolleintrag scheitern, der den Grund für den Abbruch nennt.

Lege anschließend eine operative Regel fest, die sich leicht merken lässt: Der Agent bereitet einen benannten Release-Kandidaten vor, und ein Mensch bestätigt die exakt definierte öffentliche Änderung. Wenn deine aktuelle Automatisierung in diesem Moment Repository, Commit, Artefakte und Rollback-Folgen nicht nennen kann, ist sie noch nicht bereit, Software unbeaufsichtigt zu veröffentlichen.
