GitHub release notes: genereren en dan leesbaar maken
6 min lezen
GitHub release notes zijn de beschrijving die aan een release hangt op de Releases-pagina van een repository, en GitHub kan er een eerste concept van schrijven uit de pull requests die sinds de vorige tag zijn gemerged. Het concept is een lijst van pull-requesttitels gegroepeerd per label, met een regel voor de contributors en een compare-link. Het is accuraat, compleet en geschreven voor de mensen die de pull requests mergeden. Er iets van maken wat een gebruiker van het project kan lezen vraagt een .github/release.yml-bestand en een korte bewerkingsronde, en beide staan hieronder.
| Manier om de notes te maken | Waar het draait | Wat je krijgt |
|---|---|---|
| Knop “Generate release notes” | Releaseformulier in de web-UI | PR-titels sinds de laatste tag, gegroepeerd per release.yml-categorie |
gh release create v1.4.0 --generate-notes | GitHub CLI, lokaal of in CI | Hetzelfde concept, in één commando samen met de release aangemaakt |
POST /repos/{owner}/{repo}/releases/generate-notes | REST API | Het concept als tekst, zonder een release aan te maken, voor je eigen pipeline |
| release-please, semantic-release, conventional-changelog | GitHub Actions of een releasejob | Notes uit commitberichten in plaats van PR-titels, plus versiesprongen en een CHANGELOG.md |
| Met de hand geschreven | Het releaseformulier | Wat je ook typt, zonder link terug naar de pull requests |
Hoe genereer je automatisch release notes op GitHub?
Open het releaseformulier, kies of maak de tag en klik op “Generate release notes”. GitHub zoekt de vorige releasetag op, somt elke pull request op die tussen de twee in de doelbranch is gemerged, en schrijft per pull request één regel met titel, auteur en nummer. Vanaf de commandoregel doet gh release create <tag> --generate-notes hetzelfde en publiceert het de release in één stap; --notes-start-tag bepaalt bij welke eerdere tag het bereik begint.
De functie werkt vanuit pull requests, dus een repository die rechtstreeks naar main merget zonder pull requests krijgt een leeg concept. Squash merges zijn prima, want de pull request bestaat nog. Merge-commits van een langlevende branch naar main leveren één regel op voor de mergende pull request, zonder de pull requests die eerder in die branch zijn gemerged. Ziet het bereik er verkeerd uit, dan is de oorzaak meestal een ontbrekende of verkeerd geordende vorige tag; de generator gebruikt de laatste release op de doelbranch, en een tag zonder release wordt genegeerd.
De GitHub Docs-pagina over automatisch gegenereerde release notes beschrijft de knop, en de handleiding van gh release create beschrijft de CLI-vlaggen.
Wat verandert release.yml?
.github/release.yml vertelt de generator welke pull requests hij moet weglaten en hoe hij de rest groepeert. Zonder dat bestand komt elke pull request in één lijst, Dependabot incluis. Met het bestand worden pull requests per label in categorieën gesorteerd, en verdwijnt de ruis van gelabelde of door bots geschreven pull requests.
# .github/release.yml
changelog:
exclude:
labels:
- skip-changelog
authors:
- dependabot
- renovate
categories:
- title: Breaking changes
labels:
- breaking-change
- title: Nieuw
labels:
- enhancement
- title: Opgelost
labels:
- bug
- title: Overige wijzigingen
labels:
- "*"
Drie regels om te kennen. Categorieën worden op volgorde gematcht, dus een pull request met zowel breaking-change als bug komt onder de eerste kop die past. De catch-all "*" is verplicht als je ongelabelde pull requests überhaupt wilt zien; zonder die regel vallen ze stilletjes weg. En het bestand beïnvloedt alleen wat de generator schrijft, dus een aanpassing raakt bestaande notes niet. Teams die pull requests al labelen voor een changelog-check in CI kunnen dezelfde labels hier hergebruiken.
Waarom lezen gegenereerde GitHub release notes zo slecht?
Omdat een pull-requesttitel voor de reviewer is geschreven, voordat de wijziging af was, en de code beschrijft. “Refactor export worker to use streaming” is een goede pull-requesttitel en een nutteloze release note, want wie de release leest wil weten dat exports boven 100 MB geen time-out meer geven.
De tweede reden is dat elke gemergede pull request evenveel gewicht krijgt. Een typfoutfix van één regel staat naast een nieuwe authenticatieflow, in de volgorde waarin ze gemerged werden. De lezer moet de hele lijst scannen om de drie regels te vinden die hem raken.
De derde is dat het concept geen opening heeft. Een lijst van veertig regels zonder zin erboven vertelt niemand of deze release veilig is om te nemen, een migratie vraagt of alleen bestaat om een dependency vast te pinnen.
Wat moet de bewerkingsronde veranderen?
Houd de gegenereerde lijst en voeg eraan toe, in plaats van opnieuw te beginnen. De lijst is het audittrail; de pull-requestnummers zijn hoe iemand een regel terugvolgt naar de diff. De bewerkingsronde voegt de delen toe die de generator niet kan weten.
- Schrijf twee of drie zinnen bovenaan. Waar deze release voor is, of upgraden een actie vraagt en wat je eerst moet lezen. Is er een breaking change, zeg dat dan in de eerste regel.
- Herschrijf de regels waar mensen om geven vanuit de lezer: het symptoom dat verdween, het ding dat nu kan, de instelling die verhuisde. Laat het pull-requestnummer aan het einde van de regel staan. Hoe schrijf je release notes geeft de volledige vorm; bugfix release notes behandelt specifiek de fixregels.
- Zet alles wat een lezer moet doen in een eigen sectie, met het exacte commando of de exacte instelling. Een breaking change begraven in de lijst “Overige wijzigingen” is over een week een supportticket.
- Verwijder niets uit de gegenereerde lijst. Klap hem in onder een kop “Volledige lijst van wijzigingen” als hij lang is, maar houd hem, want de contributors van het project gebruiken hem.
Zo gedaan kost het bewerken van GitHub release notes voor een gemiddelde release ongeveer tien minuten, en bedienen de notes beide doelgroepen: de samenvatting bovenaan voor gebruikers, de lijst eronder voor contributors.
Moet de GitHub-release je changelog zijn?
Alleen als iedereen die van een wijziging moet weten de Releases-pagina al leest. Voor een library die developers via een package manager binnenhalen is dat vaak zo, en dan volstaan de Releases-pagina plus een CHANGELOG.md in de repository. Voor een product met gebruikers die GitHub nooit openen niet: de releasepagina is op het verkeerde niveau geschreven, staat achter een URL voor developers en kan niet worden gevolgd door iemand zonder GitHub-account.
Het patroon dat standhoudt is de GitHub-release behandelen als het register voor developers en de productchangelog als dat voor lezers, waarbij de release naar de changelog-entry linkt. Git-tags, releases en de changelog beschrijft hoe de drie registers op elkaar aansluiten. Wordt de productchangelog uit dezelfde commits gegenereerd, dan geeft een changelog-generator ook voor die kant een concept, en de scheiding changelog vs release notes legt uit welk detail waar hoort.
Hoe versioneer je de release notes zelf?
Een gepubliceerde release op GitHub kan op elk moment worden bewerkt, en de bewerking laat geen zichtbare geschiedenis achter op de pagina. Voor de meeste projecten is dat prima. Voor projecten waar de notes een register zijn waar compliance of klanten op leunen, helpen twee gewoontes: houd de canonieke tekst in de repository (de CHANGELOG.md, of een map docs/releases/) en laat de releasetekst ernaar verwijzen, en schakel immutable releases in op de repository als je plan dat biedt, wat de tag en de assets vergrendelt zodra ze zijn gepubliceerd. De GitHub Docs over het beheren van releases beschrijven concepten, pre-releases en het label “latest”, dat op volgorde van semantische versie wordt toegekend tenzij je het met de hand instelt.
FAQ
Kunnen GitHub release notes automatisch worden gegenereerd?
Ja. De knop “Generate release notes” op het releaseformulier, de vlag --generate-notes van gh release create en het REST-endpoint generate-notes maken alle drie een concept uit de pull requests die sinds de vorige releasetag zijn gemerged. Een .github/release.yml-bestand bepaalt de groepering en de uitsluitingen.
Waarom zijn mijn gegenereerde release notes leeg? De generator somt pull requests op, dus directe commits op de branch verschijnen niet, en het bereik begint bij de laatste release op de doelbranch in plaats van bij de laatste tag. Controleer of de vorige release bestaat en of de wijzigingen via pull requests zijn binnengekomen.
Geldt release.yml voor releases die al bestaan? Nee. Het vormt alleen notes die worden gegenereerd nadat het bestand er staat. Bestaande releaseteksten blijven zoals ze waren tot iemand ze bewerkt.
Moet ik GitHub release notes gebruiken of een CHANGELOG.md? Beide, als het project contributors en gebruikers heeft. De releasepagina is waar developers kijken en waar de assets staan; het bestand in de repository overleeft een vertrek van GitHub en is offline te lezen. Genereer de release notes, houd het bestand actueel en link de een naar de ander.
De technische beweringen in dit artikel zijn niet onafhankelijk gecontroleerd. Klopt er iets niet, laat het ons weten, dan corrigeren we het.