Engineering

GitHub Release Notes: generieren, dann lesbar machen

6 Min. Lesezeit

GitHub Release Notes sind die Beschreibung, die an einem Release auf der Releases-Seite des Repositorys hängt, und GitHub kann einen ersten Entwurf davon für euch schreiben, aus den Pull Requests, die seit dem vorherigen Tag gemergt wurden. Der Entwurf ist eine Liste von Pull-Request-Titeln, nach Label gruppiert, mit einer Zeile zu den Mitwirkenden und einem Compare-Link. Er ist korrekt, vollständig und für die Leute geschrieben, die die Pull Requests gemergt haben. Ihn in etwas zu verwandeln, das eine Nutzerin des Projekts lesen kann, braucht eine Datei .github/release.yml und eine kurze Überarbeitung, und beides steht unten.

Weg zu den NotesWo er läuftWas ihr bekommt
Button “Generate release notes”Release-Formular in der Web-OberflächePR-Titel seit dem letzten Tag, gruppiert nach den Kategorien aus release.yml
gh release create v1.4.0 --generate-notesGitHub CLI, lokal oder in CIDerselbe Entwurf, zusammen mit dem Release in einem Befehl erzeugt
POST /repos/{owner}/{repo}/releases/generate-notesREST-APIDer Entwurf als Text, ohne ein Release anzulegen, für eure eigene Pipeline
release-please, semantic-release, conventional-changelogGitHub Actions oder ein Release-JobNotes aus Commit-Nachrichten statt PR-Titeln, plus Versionssprünge und eine CHANGELOG.md
Von Hand geschriebenDas Release-FormularWas immer ihr tippt, ohne Verweis zurück auf die Pull Requests

Wie generiert man Release Notes auf GitHub automatisch?

Öffnet das Release-Formular, wählt oder erstellt den Tag und klickt auf “Generate release notes”. GitHub sucht den vorherigen Release-Tag, listet jeden Pull Request, der zwischen den beiden in den Zielbranch gemergt wurde, und schreibt eine Zeile pro Pull Request mit Titel, Autorin und Nummer. Auf der Kommandozeile macht gh release create <tag> --generate-notes dasselbe und veröffentlicht das Release in einem Schritt; --notes-start-tag legt fest, bei welchem früheren Tag der Bereich beginnt.

Die Funktion arbeitet mit Pull Requests, also bekommt ein Repository, das ohne Pull Requests direkt nach main mergt, einen leeren Entwurf. Squash-Merges sind in Ordnung, weil der Pull Request weiter existiert. Merge-Commits von einem langlebigen Branch nach main ergeben eine Zeile für den mergenden Pull Request, ohne die Pull Requests, die vorher in diesen Branch gemergt wurden. Sieht der Bereich falsch aus, ist die übliche Ursache ein fehlender oder falsch geordneter vorheriger Tag; der Generator nimmt das neueste Release auf dem Zielbranch, und ein Tag ohne zugehöriges Release wird ignoriert.

Die Seite in den GitHub Docs zu automatisch generierten Release Notes beschreibt den Button, und das Handbuch zu gh release create die CLI-Flags.

Was ändert release.yml?

.github/release.yml sagt dem Generator, welche Pull Requests er weglassen und wie er den Rest gruppieren soll. Ohne die Datei landet jeder Pull Request in einer Liste, Dependabot eingeschlossen. Mit ihr werden Pull Requests nach Label in Kategorien sortiert, und gelabeltes oder von Bots erzeugtes Rauschen verschwindet.

# .github/release.yml
changelog:
  exclude:
    labels:
      - skip-changelog
    authors:
      - dependabot
      - renovate
  categories:
    - title: Breaking changes
      labels:
        - breaking-change
    - title: New
      labels:
        - enhancement
    - title: Fixed
      labels:
        - bug
    - title: Other changes
      labels:
        - "*"

Drei Regeln lohnen sich zu kennen. Kategorien werden der Reihe nach abgeglichen, also landet ein Pull Request mit breaking-change und bug unter der ersten Überschrift, die passt. Der Sammler "*" ist Pflicht, wenn ungelabelte Pull Requests überhaupt erscheinen sollen; ohne ihn fallen sie stillschweigend weg. Und die Datei beeinflusst nur, was der Generator schreibt, eine Änderung berührt also keine Notes, die schon existieren. Teams, die Pull Requests bereits für einen Changelog-Check in CI labeln, können dieselben Labels hier wiederverwenden.

Warum lesen sich generierte GitHub Release Notes schlecht?

Weil ein Pull-Request-Titel für die Reviewerin geschrieben wird, bevor die Änderung fertig ist, und den Code beschreibt. “Refactor export worker to use streaming” ist ein guter Pull-Request-Titel und eine nutzlose Release Note, denn wer das Release liest, will wissen, dass Exporte über 100 MB nicht mehr in einen Timeout laufen.

Der zweite Grund: Jeder gemergte Pull Request bekommt dasselbe Gewicht. Ein einzeiliger Tippfehler-Fix steht neben einem neuen Authentifizierungsablauf, in der Reihenfolge, in der sie gemergt wurden. Die Leserin muss die ganze Liste durchgehen, um die drei Zeilen zu finden, die sie betreffen.

Der dritte: Der Entwurf hat keinen Einstieg. Eine Liste mit vierzig Zeilen und keinem Satz darüber sagt niemandem, ob dieses Release gefahrlos zu übernehmen ist, eine Migration braucht oder nur existiert, um eine Abhängigkeit zu pinnen.

Was sollte die Überarbeitung ändern?

Behaltet die generierte Liste und ergänzt sie, statt von vorn zu schreiben. Die Liste ist der Audit-Trail; über die Pull-Request-Nummern führt jemand eine Zeile zum Diff zurück. Die Überarbeitung ergänzt die Teile, die der Generator nicht wissen kann.

  1. Schreibt zwei oder drei Sätze an den Anfang. Wofür dieses Release da ist, ob das Upgrade etwas verlangt und was zuerst zu lesen ist. Gibt es einen Breaking Change, sagt es in der ersten Zeile.
  2. Schreibt die Zeilen um, die Leute interessieren, aus Sicht der Leserin: das Symptom, das verschwunden ist, die Sache, die jetzt geht, die Einstellung, die umgezogen ist. Lasst die Pull-Request-Nummer am Ende der Zeile stehen. Wie man Release Notes schreibt beschreibt die ganze Form; Bugfix-Release-Notes behandelt speziell die Fix-Zeilen.
  3. Verschiebt alles, was eine Leserin tun muss, in einen eigenen Abschnitt, mit dem genauen Befehl oder der Einstellung. Ein Breaking Change, der in der Liste “Other changes” vergraben ist, ist in einer Woche ein Support-Ticket.
  4. Löscht nichts aus der generierten Liste. Klappt sie unter einer Überschrift “Vollständige Liste der Änderungen” ein, wenn sie lang ist, aber behaltet sie, denn die Mitwirkenden des Projekts nutzen sie.

So gemacht dauert die Überarbeitung der GitHub Release Notes bei einem typischen Release etwa zehn Minuten, und die Notes dienen beiden Zielgruppen: die Zusammenfassung oben den Nutzerinnen, die Liste darunter den Mitwirkenden.

Sollte das GitHub-Release euer Changelog sein?

Nur wenn alle, die von einer Änderung wissen müssen, die Releases-Seite ohnehin lesen. Bei einer Bibliothek, die Entwicklerinnen über einen Paketmanager beziehen, trifft das oft zu, und die Releases-Seite plus eine CHANGELOG.md im Repository reichen. Bei einem Produkt mit Nutzerinnen, die GitHub nie öffnen, nicht: Die Release-Seite ist auf der falschen Ebene geschrieben, liegt hinter einer entwicklerseitigen URL und lässt sich ohne GitHub-Konto nicht abonnieren.

Das Muster, das trägt: Das GitHub-Release ist die Aufzeichnung für Entwicklerinnen, der Produkt-Changelog die für Leserinnen, und das Release verlinkt auf den Changelog-Eintrag. Git-Tags, Releases und dein Changelog beschreibt, wie die drei Aufzeichnungen zusammenpassen. Wird der Produkt-Changelog aus denselben Commits erzeugt, liefert ein Changelog-Generator auch für diese Seite einen Entwurf, und die Trennung in Changelog vs. Release Notes erklärt, welches Detail wohin gehört.

Wie versioniert man die Release Notes selbst?

Ein veröffentlichtes Release auf GitHub lässt sich jederzeit bearbeiten, und die Bearbeitung hinterlässt auf der Seite keine sichtbare Historie. Für die meisten Projekte ist das in Ordnung. Für Projekte, bei denen Compliance oder Kundinnen sich auf die Notes als Aufzeichnung verlassen, helfen zwei Gewohnheiten: Haltet den maßgeblichen Text im Repository (die CHANGELOG.md oder ein Ordner docs/releases/) und lasst den Release-Text darauf verweisen, und aktiviert unveränderliche Releases im Repository, wenn euer Tarif sie anbietet, was Tag und Assets nach der Veröffentlichung sperrt. Die GitHub Docs zum Verwalten von Releases beschreiben Entwürfe, Pre-Releases und das Label “latest”, das nach semantischer Versionsreihenfolge vergeben wird, sofern ihr es nicht von Hand setzt.

FAQ

Lassen sich GitHub Release Notes automatisch generieren? Ja. Der Button “Generate release notes” im Release-Formular, das Flag --generate-notes bei gh release create und der REST-Endpunkt generate-notes erzeugen alle einen Entwurf aus den Pull Requests, die seit dem vorherigen Release-Tag gemergt wurden. Eine Datei .github/release.yml steuert Gruppierung und Ausschlüsse.

Warum sind meine generierten Release Notes leer? Der Generator listet Pull Requests, also erscheinen direkte Commits auf dem Branch nicht, und der Bereich beginnt beim neuesten Release auf dem Zielbranch, nicht beim neuesten Tag. Prüft, ob das vorherige Release existiert und ob die Änderungen über Pull Requests gekommen sind.

Gilt release.yml für Releases, die schon existieren? Nein. Die Datei formt nur Notes, die generiert werden, nachdem sie vorhanden ist. Bestehende Release-Texte bleiben, wie sie waren, bis jemand sie bearbeitet.

Sollte ich GitHub Release Notes oder eine CHANGELOG.md nutzen? Beides, wenn das Projekt Mitwirkende und Nutzerinnen hat. Die Release-Seite ist der Ort, an dem Entwicklerinnen nachsehen und Assets liegen; die Datei im Repository überlebt einen Umzug weg von GitHub und lässt sich offline lesen. Generiert die Release Notes, haltet die Datei aktuell und verlinkt das eine mit dem anderen.


Die technischen Aussagen in diesem Artikel wurden nicht unabhängig geprüft. Wenn etwas nicht stimmt, sagen Sie es uns, und wir korrigieren es.

Mehr bei changeloop: Changelog-Generator, Entwicklerdokumentation

changeloop
Das Team hinter einem Changelog, das den Kreis schließt. Ihre Nutzer fragen, Ihr Team liefert, und wer gefragt hat, erfährt davon.