Changelogs de monorepo : un seul, ou un par package ?
6 min de lecture
Un monorepo héberge plusieurs éléments déployables séparément dans un seul dépôt, et un changelog doit d’abord répondre à une question : le lecteur s’intéresse-t-il au repo, ou à un package particulier à l’intérieur ? La plupart des équipes ne décident jamais ça délibérément. Elles commencent avec un changelog parce qu’il y a un repo, ajoutent des packages au fil du temps, et finissent avec un journal où quelqu’un utilisant la CLI doit défiler devant quarante entrées backend sans rapport pour trouver celle qui a livré son correctif. Ce qui décide la bonne forme, ce n’est pas la structure du dépôt, mais qui lit le journal et ce qu’il sait déjà chercher.
Qu’est-ce qui rend le changelog d’un monorepo différent de celui d’un repo unique ?
Un changelog de repo unique a un public implicite : tous ceux qui utilisent l’unique chose que ce repo construit. Le public d’un monorepo se divise par package, et les packages du même repo sont souvent livrés selon des calendriers différents, à des consommateurs différents, à des niveaux de stabilité différents. Une bibliothèque publiée dans un registre et un outil d’administration interne peuvent vivre dans le même monorepo et n’avoir presque rien en commun pour qui lit le changelog.
| Forme du repo | Lecteur typique | Changelog adapté |
|---|---|---|
| Une seule app déployable | Tous ceux qui utilisent le produit | Un journal, pour tout le repo |
| Workspace de bibliothèques (plusieurs packages publiés) | Qui dépend d’un package particulier | Un journal par package |
| App plus outillage interne | Deux publics distincts sans recouvrement | Divisé par public, pas par dossier |
| App plus son propre SDK | Utilisateurs du produit, et intégrateurs du SDK | Deux journaux : un pour le produit, un pour le SDK |
Chaque package a-t-il besoin de son propre changelog ?
Seulement ceux avec un public indépendant. Un package publié dans un registre a besoin de son
propre journal, parce que la personne qui l’installe n’a aucune raison de lire quoi que ce soit
d’autre dans le repo, et les outils de release de monorepo comme Lerna et
Changesets écrivent un CHANGELOG.md par package, à côté de son package.json. Un utilitaire interne avec un
seul consommateur, l’app déjà présente dans le même repo, n’a pas besoin d’un journal séparé ;
intégrer ses changements dans les entrées de cette app est plus utile qu’un second fichier que
personne en dehors de l’équipe n’ouvre.
Le test est le même que celui qui décide si une entrée quelconque appartient à un changelog : le lecteur le remarquerait-il ou s’en soucierait-il, et peut-il agir en le sachant. Applique-le par package, pas par dossier, et un repo avec douze packages peut finir avec deux vrais changelogs et dix packages qui n’en ont tout simplement pas besoin.
Comment sait-on quel package a causé quelle entrée de changelog ?
Étiquette chaque entrée avec son package au moment où elle est écrite, pas après coup en inspectant quels fichiers un commit a touchés. Un commit qui corrige une bibliothèque interne partagée peut produire une entrée de changelog dans chaque package qui en dépend, et les chemins de fichiers seuls ne peuvent pas dire laquelle de ces entrées en aval le lecteur doit vraiment voir ; seule une personne qui décide “ceci est visible pour qui utilise le package A et pas pour qui utilise le package B” le peut. Les conventional commits aident ici mécaniquement, en nommant le package dans chaque commit, mais le scope ne produit toujours qu’un brouillon. La même règle à deux niveaux de cet article s’applique par package : un brouillon avec le bon scope a quand même besoin d’un passage humain avant d’être formulé pour le lecteur réel de ce package.
De quoi un changelog partagé a-t-il besoin qu’un changelog de repo unique n’a pas ?
Une étiquette de package sur chaque entrée, en tout premier, avant la description, pour qu’un lecteur qui parcourt le journal puisse sauter en une seule passe tout ce qui ne le concerne pas. Sans cette étiquette, un journal partagé se lit comme un flux aléatoire, et un lecteur qui s’intéresse à un package n’a aucun moyen de le filtrer sauf mémoriser quelles lignes comptent, ce que personne ne fait après la première semaine.
## 2026-09-07
### [cli] Ajouté
- `acme push --dry-run` montre ce qui serait envoyé sans
l'envoyer réellement.
### [core] Corrigé
- Le backoff des tentatives ne se réinitialise plus sur une
requête réussie qui renvoie un corps vide.
Deux entrées, deux publics, un coup d’œil pour les distinguer. Un workflow façon Changesets intègre cet étiquetage directement dans le processus de release : un contributeur écrit une note courte, avec le scope du package, à côté de son changement, et l’outil assemble les changelogs par package et les montées de version à partir de ces notes au moment de la release, plutôt que d’essayer de reconstruire les frontières des packages après coup à partir d’un historique de commits fusionné.
Comment le versioning s’articule-t-il avec un changelog de monorepo ?
Les packages versionnés indépendamment ont besoin de leur propre changelog parce qu’ils ont leur propre numéro de version, et un changelog partagé ne peut pas exprimer “le package A est passé de 2.1 à 2.2 pendant que le package B est resté à 1.4” sans devenir deux journaux dans un seul fichier. Semantic versioning et votre changelog couvre comment un numéro de version devrait correspondre aux catégories de changelog ; dans un monorepo, cette correspondance doit s’appliquer par package, parce qu’un changement cassant dans un package n’en est pas un pour un package frère qui n’en dépend pas.
Un repo qui livre un produit comme une seule unité déployable, même s’il est construit à partir de nombreux packages internes, n’a pas ce problème : les packages partagent une version parce qu’ils sont toujours livrés ensemble, et un changelog unique est correct.
Comment les tags git s’intègrent-ils dans un monorepo ?
La même règle de tags git, releases et votre changelog
s’applique, par package : un package avec sa propre version a besoin de son propre préfixe de tag,
typiquement nom-du-package@1.4.0 plutôt qu’un v1.4.0 nu qui ne peut pas dire à quel package il
appartient. Un monorepo tagué seulement avec des numéros de version nus ne peut pas répondre plus
tard “qu’y avait-il dans core quand cli a livré la 2.2”, parce que rien sur le disque
n’enregistre à quel package ce tag appartenait réellement.
FAQ
Ai-je besoin d’un changelog séparé pour chaque package d’un monorepo ? Seulement pour les packages avec un public indépendant, généralement tout ce qui est publié dans un registre. Un package avec un seul consommateur interne déjà présent dans le même repo peut s’intégrer dans le journal de ce consommateur plutôt que d’en maintenir un propre.
Qu’est-ce qui étiquette une entrée de changelog avec le bon package ? La personne qui écrit l’entrée, au moment où elle l’écrit, pas un scan automatique des chemins de fichiers modifiés. Un changement dans une bibliothèque partagée peut produire une entrée différente dans chaque package qui en dépend, et seule une personne peut décider ce que chacune de ces entrées en aval devrait vraiment dire.
Un monorepo devrait-il utiliser un seul numéro de version pour tout ? Seulement si chaque package est toujours livré avec les autres. Si les packages sont un jour publiés indépendamment, ils ont besoin de versions indépendantes, et les versions indépendantes ont besoin de changelogs indépendants pour avoir un sens.
Un outil de changelog de monorepo remplace-t-il l’étape d’édition humaine ? Non. Des outils comme Changesets automatisent la collecte et l’assemblage des notes par package au moment de la release ; la note elle-même, écrite dans le langage du lecteur plutôt que celui du contributeur, reste le travail d’une personne, comme dans n’importe quelle autre pipeline de changelog.
Les affirmations techniques de cet article n'ont pas été vérifiées de façon indépendante. Si quelque chose est faux, dis-le-nous et nous le corrigerons.