Changelog nei monorepo: uno solo, o uno per pacchetto?
5 min di lettura
Un monorepo ospita più cose rilasciabili separatamente in un solo repository, e un changelog deve prima rispondere a una domanda: al lettore interessa il repo, o gli interessa un pacchetto specifico al suo interno? La maggior parte dei team non lo decide mai apposta. Iniziano con un changelog perché c’è un repo, aggiungono pacchetti via via, e finiscono con un log dove chi usa la CLI deve scorrere quaranta voci del backend che non gli interessano per trovare quella che ha rilasciato la sua correzione. Ciò che decide la forma giusta non è la struttura del repository, ma chi legge il log e cosa già sa di cercare.
Cosa rende diverso il changelog di un monorepo da quello di un repo singolo?
Un changelog di repo singolo ha un pubblico implicito: chiunque usi l’unica cosa che quel repo costruisce. Il pubblico di un monorepo si divide per pacchetto, e i pacchetti nello stesso repo spesso vengono rilasciati con calendari diversi, a consumatori diversi, con livelli di stabilità diversi. Una libreria pubblicata in un registro e uno strumento amministrativo interno possono convivere nello stesso monorepo e non avere quasi nulla in comune per chi legge il changelog.
| Forma del repo | Lettore tipico | Changelog adatto |
|---|---|---|
| Una singola app rilasciabile | Chiunque usi il prodotto | Un log, per tutto il repo |
| Workspace di librerie (più pacchetti pubblicati) | Chi dipende da un pacchetto specifico | Un log per pacchetto |
| App più strumenti interni | Due pubblici diversi senza sovrapposizione | Diviso per pubblico, non per cartella |
| App più il proprio SDK | Utenti del prodotto, e integratori dell’SDK | Due log: uno per il prodotto, uno per l’SDK |
Ogni pacchetto ha bisogno del proprio changelog?
Solo quelli con un pubblico indipendente. Un pacchetto pubblicato in un registro ha bisogno del
proprio log, perché chi lo installa non ha motivo di leggere altro nel repo, e gli
strumenti di rilascio per monorepo come Lerna e Changesets scrivono un
CHANGELOG.md per pacchetto, accanto al suo package.json. Un’utility interna con un solo consumatore, l’app già presente
nello stesso repo, non ha bisogno di un log separato; incorporare i suoi cambiamenti nelle voci di
quell’app è più utile di un secondo file che nessuno fuori dal team apre.
Il test è lo stesso che decide se una voce qualsiasi appartiene a un changelog: il lettore lo noterebbe o gli interesserebbe, e può agire sapendolo. Applicalo per pacchetto, non per cartella, e un repo con dodici pacchetti può finire con due changelog veri e dieci pacchetti che semplicemente non ne hanno bisogno.
Come si sa quale pacchetto ha causato quale voce di changelog?
Etichetta ogni voce con il suo pacchetto nel momento in cui viene scritta, non dopo, ispezionando quali file ha toccato un commit. Un commit che corregge una libreria interna condivisa può produrre una voce di changelog in ogni pacchetto che ne dipende, e i percorsi dei file da soli non possono dire quale di queste voci a valle il lettore debba davvero vedere; solo una persona che decide “questo è visibile a chi usa il pacchetto A e non a chi usa il pacchetto B” può farlo. I conventional commits aiutano qui meccanicamente, nominando il pacchetto in ogni commit, ma lo scope produce comunque solo una bozza. La stessa regola a due livelli di quell’articolo si applica per pacchetto: una bozza con lo scope giusto ha comunque bisogno di un passaggio umano prima di essere scritta per il lettore reale di quel pacchetto.
Cosa serve a un changelog condiviso che uno di repo singolo non richiede?
Un’etichetta di pacchetto su ogni voce, all’inizio, prima della descrizione, così chi scorre il log può saltare in un solo passaggio tutto ciò che non lo riguarda. Senza quell’etichetta, un log condiviso si legge come un feed casuale, e chi si interessa a un pacchetto non ha modo di filtrarlo se non memorizzare quali righe contano, cosa che nessuno fa dopo la prima settimana.
## 2026-09-07
### [cli] Aggiunto
- `acme push --dry-run` mostra cosa verrebbe inviato senza
inviarlo davvero.
### [core] Corretto
- Il backoff dei retry non si azzera più con una richiesta
riuscita che restituisce un corpo vuoto.
Due voci, due pubblici, un’occhiata per distinguerle. Un flusso in stile Changesets integra questa etichettatura direttamente nel processo di release: chi contribuisce scrive una nota breve, con lo scope del pacchetto, insieme alla propria modifica, e lo strumento assembla i changelog per pacchetto e i salti di versione da quelle note al momento della release, invece di provare a ricostruire i confini dei pacchetti a posteriori da una cronologia di commit unificata.
Come si intreccia il versioning con un changelog di monorepo?
I pacchetti versionati in modo indipendente hanno bisogno del proprio changelog perché hanno un proprio numero di versione, e un changelog condiviso non può esprimere “il pacchetto A è passato da 2.1 a 2.2 mentre il pacchetto B è rimasto a 1.4” senza diventare due log dentro un file. Semantic versioning e il tuo changelog copre come un numero di versione dovrebbe mappare sulle categorie del changelog; in un monorepo quella mappatura va applicata per pacchetto, perché un breaking change in un pacchetto non lo è per un pacchetto gemello che non ne dipende.
Un repo che rilascia un prodotto come un’unica unità rilasciabile, anche se costruito da molti pacchetti interni, non ha questo problema: i pacchetti condividono la versione perché vengono sempre rilasciati insieme, e un changelog unico è corretto.
Come si inseriscono i tag git in un monorepo?
Vale la stessa regola di tag git, release e il tuo changelog,
applicata per pacchetto: un pacchetto con versione propria ha bisogno del proprio prefisso di tag,
tipicamente nome-pacchetto@1.4.0 invece di un v1.4.0 nudo che non può dire a quale pacchetto
appartiene. Un monorepo taggato solo con numeri di versione nudi non può poi rispondere “cosa c’era
in core quando cli ha rilasciato la 2.2”, perché nulla su disco registra a quale pacchetto
appartenesse davvero quel tag.
FAQ
Serve un changelog separato per ogni pacchetto di un monorepo? Solo per i pacchetti con pubblico indipendente, di solito qualsiasi cosa pubblicata in un registro. Un pacchetto con un solo consumatore interno già presente nello stesso repo può confluire nel log di quel consumatore invece di mantenerne uno proprio.
Cosa etichetta una voce di changelog con il pacchetto giusto? Chi scrive la voce, nel momento in cui la scrive, non una scansione automatica dei percorsi di file modificati. Un cambiamento in una libreria condivisa può produrre una voce diversa in ogni pacchetto che ne dipende, e solo una persona può decidere cosa dovrebbe davvero dire ciascuna di quelle voci a valle.
Un monorepo dovrebbe usare un unico numero di versione per tutto? Solo se ogni pacchetto viene sempre rilasciato insieme agli altri. Se i pacchetti vengono mai pubblicati in modo indipendente, hanno bisogno di versioni indipendenti, e le versioni indipendenti hanno bisogno di changelog indipendenti per avere senso.
Uno strumento per il changelog di un monorepo sostituisce il passaggio di editing umano? No. Strumenti come Changesets automatizzano la raccolta e l’assemblaggio delle note per pacchetto al momento della release; la nota in sé, scritta nel linguaggio del lettore invece che di chi contribuisce, resta comunque compito di una persona, come in qualsiasi altra pipeline di changelog.
Le affermazioni tecniche di questo articolo non sono state verificate in modo indipendente. Se qualcosa non è corretto, faccelo sapere e lo correggeremo.