Changelog-uri de monorepo: unul singur, sau unul pe pachet?
5 min de citit
Un monorepo găzduiește mai multe lucruri lansate separat într-un singur repository, iar un changelog trebuie mai întâi să răspundă la o întrebare: cititorului îi pasă de repo, sau îi pasă de un anumit pachet din interior? Majoritatea echipelor nu decid asta niciodată intenționat. Încep cu un changelog pentru că există un repo, adaugă pachete în timp, și ajung cu un jurnal în care cineva care folosește CLI-ul trebuie să deruleze pe lângă patruzeci de intrări de backend fără legătură ca să găsească pe cea care a lansat corecția lui. Ceea ce decide forma corectă nu e structura repository-ului, ci cine citește jurnalul și ce știe deja că caută.
Ce face changelog-ul unui monorepo diferit de cel al unui repo unic?
Un changelog de repo unic are un public implicit: toți cei care folosesc singurul lucru pe care îl construiește acel repo. Publicul unui monorepo se împarte pe pachet, iar pachetele din același repo sunt adesea lansate după programe diferite, către consumatori diferiți, la niveluri diferite de stabilitate. O bibliotecă publicată într-un registru și un instrument administrativ intern pot trăi în același monorepo și să nu aibă aproape nimic în comun pentru cine citește changelog-ul.
| Forma repo-ului | Cititor tipic | Changelog potrivit |
|---|---|---|
| O singură aplicație lansată | Toți cei care folosesc produsul | Un jurnal, pentru tot repo-ul |
| Workspace de biblioteci (mai multe pachete publicate) | Cine depinde de un anumit pachet | Un jurnal pe pachet |
| Aplicație plus unelte interne | Două publicuri diferite fără suprapunere | Împărțit după public, nu după folder |
| Aplicație plus propriul SDK | Utilizatorii produsului, și integratorii SDK-ului | Două jurnale: unul pentru produs, unul pentru SDK |
Are nevoie fiecare pachet de propriul changelog?
Doar cele cu public independent. Un pachet publicat într-un registru are nevoie de propriul
jurnal, pentru că persoana care îl instalează nu are niciun motiv să citească altceva din repo, iar
uneltele de lansare pentru monorepo precum Lerna și Changesets scriu un
CHANGELOG.md pentru fiecare pachet, lângă package.json-ul lui. Un utilitar intern cu un singur consumator,
aplicația care deja trăiește în același repo, nu are nevoie de un jurnal separat; includerea
schimbărilor lui în intrările acelei aplicații e mai utilă decât un al doilea fișier pe care nimeni
din afara echipei nu îl deschide.
Testul e același care decide dacă orice intrare aparține unui changelog: cititorul ar observa sau i-ar păsa, și poate acționa știind asta. Aplică-l pe pachet, nu pe folder, iar un repo cu douăsprezece pachete poate ajunge cu două changelog-uri reale și pachete care pur și simplu nu au nevoie de unul.
Cum se știe ce pachet a cauzat ce intrare de changelog?
Etichetează fiecare intrare cu pachetul ei în momentul în care e scrisă, nu ulterior inspectând ce fișiere a atins un commit. Un commit care repară o bibliotecă internă partajată poate produce o intrare de changelog în fiecare pachet care depinde de ea, iar căile fișierelor singure nu pot spune care dintre aceste intrări din aval trebuie cu adevărat văzută de cititor; doar o persoană care decide “asta e vizibilă pentru cine folosește pachetul A și nu pentru cine folosește pachetul B” poate face asta. Conventional commits ajută aici mecanic, numind pachetul în fiecare commit, dar scope-ul tot produce doar o ciornă. Aceeași regulă pe două niveluri din acel articol se aplică pe pachet: o ciornă cu scope-ul corect tot are nevoie de o trecere umană înainte de a fi formulată pentru cititorul real al acelui pachet.
De ce are nevoie un changelog partajat pe care unul de repo unic nu îl are?
O etichetă de pachet pe fiecare intrare, chiar la început, înainte de descriere, ca un cititor care parcurge jurnalul să poată sări dintr-o singură trecere tot ce nu e al lui. Fără acea etichetă, un jurnal partajat se citește ca un flux aleatoriu, iar un cititor interesat de un pachet nu are cum să îl filtreze decât memorând ce linii contează, ceea ce nimeni nu face după prima săptămână.
## 2026-09-07
### [cli] Adăugat
- `acme push --dry-run` arată ce s-ar trimite fără să
trimită efectiv.
### [core] Reparat
- Backoff-ul reîncercărilor nu se mai resetează la o cerere
reușită care returnează un corp gol.
Două intrări, două publicuri, o privire ca să le distingi. Un flux de lucru în stilul Changesets integrează această etichetare direct în procesul de lansare: cine contribuie scrie o notă scurtă, cu scope de pachet, alături de schimbarea lui, iar unealta asamblează changelog-urile pe pachet și salturile de versiune din acele note în momentul lansării, în loc să încerce să reconstruiască granițele pachetelor ulterior dintr-un istoric de commit-uri unificat.
Cum se leagă versionarea de un changelog de monorepo?
Pachetele versionate independent au nevoie de propriul changelog pentru că au propriul număr de versiune, iar un changelog partajat nu poate exprima “pachetul A a trecut de la 2.1 la 2.2 în timp ce pachetul B a rămas la 1.4” fără să devină două jurnale într-un singur fișier. Semantic versioning și changelog-ul tău acoperă cum ar trebui să se mapeze un număr de versiune la categoriile de changelog; într-un monorepo, acea mapare trebuie aplicată pe pachet, pentru că o schimbare care rupe compatibilitatea într-un pachet nu e o schimbare care rupe compatibilitatea pentru un pachet-soră care nu depinde de el.
Un repo care lansează un produs ca o singură unitate lansată, chiar dacă e construit din multe pachete interne, nu are această problemă: pachetele împart o versiune pentru că sunt lansate mereu împreună, iar un singur changelog e corect.
Cum se potrivesc tag-urile git într-un monorepo?
Aceeași regulă din tag-uri git, lansări și changelog-ul tău
se aplică, pe pachet: un pachet cu propria versiune are nevoie de propriul prefix de tag, de obicei
nume-pachet@1.4.0 în loc de un v1.4.0 gol care nu poate spune cărui pachet îi aparține. Un
monorepo etichetat doar cu numere de versiune goale nu poate răspunde ulterior “ce era în core
când cli a lansat 2.2”, pentru că nimic de pe disc nu înregistrează cărui pachet îi aparținea
efectiv acel tag.
FAQ
Am nevoie de un changelog separat pentru fiecare pachet dintr-un monorepo? Doar pentru pachetele cu public independent, de obicei tot ce e publicat într-un registru. Un pachet cu un singur consumator intern care deja trăiește în același repo poate intra în jurnalul acelui consumator în loc să întrețină unul propriu.
Ce etichetează o intrare de changelog cu pachetul corect? Persoana care scrie intrarea, în momentul în care o scrie, nu o scanare automată a căilor de fișiere modificate. O schimbare într-o bibliotecă partajată poate produce o intrare diferită în fiecare pachet care depinde de ea, iar doar un om poate decide ce ar trebui să spună cu adevărat fiecare dintre acele intrări din aval.
Ar trebui un monorepo să folosească un singur număr de versiune pentru tot? Doar dacă fiecare pachet e lansat mereu împreună cu celelalte. Dacă pachetele sunt vreodată publicate independent, au nevoie de versiuni independente, iar versiunile independente au nevoie de changelog-uri independente ca să aibă sens.
O unealtă de changelog pentru monorepo înlocuiește pasul de editare umană? Nu. Unelte precum Changesets automatizează colectarea și asamblarea notelor pe pachet în momentul lansării; nota în sine, scrisă în limbajul cititorului în loc de cel al contribuitorului, rămâne tot munca unei persoane, la fel ca în orice alt pipeline de changelog.
Afirmațiile tehnice din acest articol nu au fost verificate independent. Dacă ceva nu e corect, spune-ne și vom corecta.