Engineering

Monorepo-Changelogs: Einer, oder einer pro Paket?

5 Min. Lesezeit

Ein Monorepo enthält mehrere eigenständig ausgelieferte Dinge in einem Repository, und ein Changelog muss zuerst eine Frage beantworten: Interessiert sich die Leserin für das Repo, oder für ein einzelnes Paket darin? Die meisten Teams entscheiden das nie bewusst. Sie fangen mit einem Changelog an, weil es ein Repo gibt, fügen immer mehr Pakete hinzu, und landen bei einem Log, in dem ein CLI-Nutzer an vierzig unrelated Backend-Einträgen vorbeiscrollen muss, um den Eintrag zu finden, der seinen Fix ausgeliefert hat. Was die richtige Form entscheidet, ist nicht die Struktur des Repositorys, sondern wer das Log liest und was er schon weiß, wonach er sucht.

Was macht das Changelog eines Monorepos anders als das eines einzelnen Repos?

Ein Changelog für ein einzelnes Repo hat ein implizites Publikum: alle, die das eine Ding nutzen, das dieses Repo baut. Das Publikum eines Monorepos teilt sich nach Paket, und Pakete im selben Repo werden oft nach unterschiedlichen Zeitplänen ausgeliefert, an unterschiedliche Abnehmer, auf unterschiedlichen Stabilitätsstufen. Eine in einer Registry veröffentlichte Bibliothek und ein internes Admin-Tool können im selben Monorepo leben und für eine Changelog-Leserin fast nichts gemeinsam haben.

Repo-FormTypische LeserinChangelog, das passt
Eine einzelne ausgelieferte AppAlle, die das Produkt nutzenEin Log, für das ganze Repo
Bibliotheks-Workspace (mehrere veröffentlichte Pakete)Wer von einem bestimmten Paket abhängtEin Log pro Paket
App plus interne ToolsZwei verschiedene Publika ohne ÜberschneidungGetrennt nach Publikum, nicht nach Ordner
App plus eigenes SDKProduktnutzer, und SDK-IntegratorenZwei Logs: produktbezogen und SDK-bezogen

Braucht jedes Paket sein eigenes Changelog?

Nur die mit einem eigenständigen Publikum. Ein in einer Registry veröffentlichtes Paket braucht sein eigenes Log, weil die Person, die es installiert, keinen Grund hat, irgendetwas anderes im Repo zu lesen, und Monorepo-Release-Tools wie Lerna und Changesets schreiben eine CHANGELOG.md pro Paket, neben dessen package.json. Ein internes Hilfsprogramm mit einem Abnehmer, der App, die schon im selben Repo lebt, braucht kein eigenes Log; seine Änderungen in die Einträge dieser App einzuflechten ist nützlicher als eine zweite Datei, die außerhalb des Teams niemand öffnet.

Der Test ist derselbe, der entscheidet, ob ein einzelner Eintrag überhaupt in ein Changelog gehört: würde die Leserin es bemerken oder sich dafür interessieren, und kann sie danach handeln. Wende ihn pro Paket an, nicht pro Ordner, und ein Repo mit zwölf Paketen kann am Ende zwei echte Changelogs haben, und zehn Pakete, die schlicht keins brauchen.

Woher weiß man, welches Paket welchen Changelog-Eintrag verursacht hat?

Markiere jeden Eintrag mit seinem Paket in dem Moment, in dem der Eintrag geschrieben wird, nicht im Nachhinein durch Untersuchen, welche Dateien ein Commit berührt hat. Ein Commit, der eine gemeinsam genutzte interne Bibliothek repariert, kann in jedem Paket, das davon abhängt, einen Changelog-Eintrag erzeugen, und Dateipfade allein können nicht sagen, welcher dieser nachgelagerten Einträge eine Leserin tatsächlich sehen muss; nur eine Person, die entscheidet “das ist für Nutzerinnen von Paket A sichtbar und nicht von Paket B”, kann das. Conventional Commits helfen hier mechanisch, indem sie das Paket in jedem Commit benennen, aber der Scope erzeugt trotzdem nur einen Entwurf. Dieselbe Zwei-Schichten-Regel aus diesem Artikel gilt pro Paket: ein Entwurf mit dem richtigen Scope braucht trotzdem einen menschlichen Durchgang, bevor er für das tatsächliche Publikum dieses Pakets formuliert ist.

Was braucht ein gemeinsames Changelog, das ein Changelog für ein einzelnes Repo nicht braucht?

Eine Paket-Kennzeichnung an jedem Eintrag, ganz vorne, vor der Beschreibung, damit eine Leserin, die das Log überfliegt, in einem Durchgang alles überspringen kann, was nicht ihres ist. Ohne diese Kennzeichnung liest sich ein gemeinsames Log wie ein zufälliger Feed, und eine Leserin, die sich für ein Paket interessiert, hat keine Möglichkeit, es zu filtern, außer sich zu merken, welche Zeilen zählen, was niemand nach der ersten Woche noch tut.

## 2026-09-07

### [cli] Hinzugefügt
- `acme push --dry-run` zeigt, was gesendet würde, ohne es zu senden.

### [core] Behoben
- Der Retry-Backoff setzt sich nicht mehr bei einer erfolgreichen
  Anfrage mit leerem Body zurück.

Zwei Einträge, zwei Publika, ein Blick genügt, um sie zu unterscheiden. Ein Workflow im Stil von Changesets baut diese Kennzeichnung direkt in den Release-Prozess ein: eine mitwirkende Person schreibt eine kurze, paketbezogene Notiz neben ihrer Änderung, und das Tool setzt paketbezogene Changelogs und Versionssprünge zur Release-Zeit aus diesen Notizen zusammen, statt zu versuchen, Paketgrenzen im Nachhinein aus einer zusammengeführten Commit-Historie zu rekonstruieren.

Wie hängt Versionierung mit einem Monorepo-Changelog zusammen?

Unabhängig versionierte Pakete brauchen ihr eigenes Changelog, weil sie ihre eigene Versionsnummer haben, und ein gemeinsames Changelog kann nicht ausdrücken “Paket A ging von 2.1 auf 2.2, während Paket B bei 1.4 blieb”, ohne zu zwei Logs in einer Datei zu werden. Semantic Versioning und dein Changelog behandelt, wie eine Versionsnummer auf Changelog-Kategorien abgebildet werden sollte; in einem Monorepo muss diese Abbildung pro Paket angewendet werden, weil eine Breaking Change in einem Paket keine Breaking Change für ein Geschwisterpaket ist, das nicht davon abhängt.

Ein Repo, das ein Produkt als eine ausgelieferte Einheit ausliefert, auch wenn es aus vielen internen Paketen gebaut ist, hat dieses Problem nicht: die Pakete teilen sich eine Version, weil sie immer nur zusammen released werden, und ein einziges Changelog ist richtig.

Wie passen Git-Tags in ein Monorepo?

Dieselbe Regel aus Git-Tags, Releases und dein Changelog gilt, pro Paket angewendet: ein Paket mit eigener Version braucht ein eigenes Tag-Präfix, typischerweise paketname@1.4.0 statt eines nackten v1.4.0, das nicht sagen kann, zu welchem Paket es gehört. Ein Monorepo, das nur mit nackten Versionsnummern getaggt wird, kann später nicht beantworten “was war in core, als cli 2.2 auslieferte”, weil nichts auf der Platte festhält, für welches Paket dieses Tag eigentlich stand.

FAQ

Brauche ich für jedes Paket in einem Monorepo ein eigenes Changelog? Nur für Pakete mit eigenständigem Publikum, meist alles, was in einer Registry veröffentlicht wird. Ein Paket mit einem internen Abnehmer, der schon im selben Repo lebt, kann sich in dessen Log einfügen, statt ein eigenes zu pflegen.

Was kennzeichnet einen Changelog-Eintrag mit dem richtigen Paket? Die Person, die den Eintrag schreibt, zum Zeitpunkt des Schreibens, nicht ein automatischer Scan geänderter Dateipfade. Eine Änderung an einer gemeinsamen Bibliothek kann in jedem abhängigen Paket einen anderen Eintrag erzeugen, und nur ein Mensch kann entscheiden, was jeder dieser nachgelagerten Einträge tatsächlich sagen soll.

Sollte ein Monorepo eine Versionsnummer für alles verwenden? Nur, wenn jedes Paket immer zusammen ausgeliefert wird. Werden Pakete jemals unabhängig veröffentlicht, brauchen sie unabhängige Versionen, und unabhängige Versionen brauchen unabhängige Changelogs, um sinnvoll zu sein.

Ersetzt ein Monorepo-Changelog-Tool den menschlichen Bearbeitungsschritt? Nein. Tools wie Changesets automatisieren das Sammeln und Zusammensetzen paketbezogener Notizen zur Release-Zeit; die Notiz selbst, geschrieben in der Sprache der Leserin statt der der mitwirkenden Person, bleibt genauso Aufgabe eines Menschen wie bei jeder anderen Changelog-Pipeline.


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.