Ingeniería

Changelogs en monorepo: ¿uno solo, o uno por paquete?

6 min de lectura

Un monorepo aloja varias cosas desplegables por separado en un solo repositorio, y un changelog tiene que responder primero una pregunta: ¿al lector le importa el repo, o le importa un paquete concreto dentro de él? La mayoría de equipos nunca deciden esto a propósito. Empiezan con un changelog porque hay un repo, van añadiendo paquetes, y terminan con un log donde alguien que usa la CLI tiene que pasar cuarenta entradas del backend que no le importan para encontrar la que lanzó su corrección. Lo que decide la forma correcta no es la estructura del repositorio, sino quién lee el log y qué es lo que ya sabe que está buscando.

¿Qué hace distinto el changelog de un monorepo del de un repo único?

Un changelog de repo único tiene un público implícito: todo el mundo que usa lo único que ese repo construye. El público de un monorepo se divide por paquete, y los paquetes dentro del mismo repo suelen lanzarse en calendarios distintos, a consumidores distintos, con niveles de estabilidad distintos. Una biblioteca publicada en un registro y una herramienta de administración interna pueden vivir en el mismo monorepo y no tener casi nada en común para quien lee el changelog.

Forma del repoLector típicoChangelog que encaja
Una sola app desplegableTodo el mundo que usa el productoUn log, para todo el repo
Workspace de bibliotecas (varios paquetes publicados)Quien depende de un paquete concretoUn log por paquete
App más herramientas internasDos públicos distintos sin solapeDividido por público, no por carpeta
App más su propio SDKUsuarios del producto, e integradores del SDKDos logs: uno del producto, otro del SDK

¿Necesita cada paquete su propio changelog?

Solo los que tienen un público independiente. Un paquete publicado en un registro necesita su propio log, porque quien lo instala no tiene motivo para leer nada más del repo, y las herramientas de lanzamiento para monorepos como Lerna y Changesets escriben un CHANGELOG.md por paquete, junto a su package.json. Una utilidad interna con un único consumidor, la app que ya vive en el mismo repo, no necesita un log separado; incorporar sus cambios en las entradas de esa app es más útil que un segundo archivo que nadie fuera del equipo abre.

La prueba es la misma que decide si una entrada cualquiera pertenece a un changelog: si el lector lo notaría o le importaría, y si puede actuar al saberlo. Aplícala por paquete, no por carpeta, y un repo con doce paquetes puede terminar con dos changelogs reales y diez paquetes que simplemente no necesitan ninguno.

¿Cómo se sabe qué paquete causó qué entrada de changelog?

Etiqueta cada entrada con su paquete en el momento en que se escribe, no después inspeccionando qué archivos tocó un commit. Un commit que corrige una biblioteca interna compartida puede producir una entrada de changelog en cada paquete que depende de ella, y las rutas de archivo por sí solas no pueden decir cuál de esas entradas derivadas necesita ver realmente el lector; solo una persona que decide “esto es visible para quien usa el paquete A y no para quien usa el paquete B” puede hacerlo. Los conventional commits ayudan aquí mecánicamente, nombrando el paquete en cada commit, pero el scope solo produce un borrador. La misma regla de dos capas de ese artículo aplica por paquete: un borrador con el scope correcto sigue necesitando un pase humano antes de estar redactado para el lector real de ese paquete.

¿Qué necesita un changelog compartido que uno de repo único no necesita?

Una etiqueta de paquete en cada entrada, al principio, antes de la descripción, para que un lector que revisa el log pueda saltarse en una sola pasada todo lo que no es suyo. Sin esa etiqueta, un log compartido se lee como un feed aleatorio, y un lector que se interesa por un paquete no tiene forma de filtrarlo salvo memorizar qué líneas importan, algo que nadie hace pasada la primera semana.

## 2026-09-07

### [cli] Añadido
- `acme push --dry-run` muestra qué se enviaría sin enviarlo.

### [core] Corregido
- El backoff de reintentos ya no se reinicia con una solicitud
  exitosa que devuelve un cuerpo vacío.

Dos entradas, dos públicos, un vistazo para distinguirlas. Un flujo al estilo Changesets integra este etiquetado directamente en el proceso de lanzamiento: quien contribuye escribe una nota corta y con scope de paquete junto a su cambio, y la herramienta ensambla los changelogs por paquete y los saltos de versión a partir de esas notas en el momento del lanzamiento, en lugar de intentar reconstruir los límites de paquete a posteriori a partir de un historial de commits fusionado.

¿Cómo se relaciona el versionado con un changelog de monorepo?

Los paquetes versionados de forma independiente necesitan su propio changelog porque tienen su propio número de versión, y un changelog compartido no puede expresar “el paquete A pasó de 2.1 a 2.2 mientras el paquete B se quedó en 1.4” sin convertirse en dos logs dentro de un archivo. Semantic versioning y tu changelog cubre cómo debería mapearse un número de versión a las categorías del changelog; en un monorepo ese mapeo hay que aplicarlo por paquete, porque un breaking change en un paquete no lo es para un paquete hermano que no depende de él.

Un repo que lanza un producto como una sola unidad desplegable, aunque esté construido a partir de muchos paquetes internos, no tiene este problema: los paquetes comparten versión porque siempre se lanzan juntos, y un único changelog es lo correcto.

¿Cómo encajan los tags de git en un monorepo?

Aplica la misma regla de tags de git, releases y tu changelog, por paquete: un paquete con versión propia necesita su propio prefijo de tag, típicamente nombre-del-paquete@1.4.0 en lugar de un v1.4.0 desnudo que no puede decir a qué paquete pertenece. Un monorepo etiquetado solo con números de versión desnudos no puede responder después “qué había en core cuando cli lanzó la 2.2”, porque nada en disco registra a qué paquete pertenecía realmente ese tag.

FAQ

¿Necesito un changelog separado para cada paquete de un monorepo? Solo para los paquetes con público independiente, casi siempre cualquier cosa publicada en un registro. Un paquete con un único consumidor interno que ya vive en el mismo repo puede incorporarse al log de ese consumidor en lugar de mantener uno propio.

¿Qué etiqueta una entrada de changelog con el paquete correcto? La persona que escribe la entrada, en el momento de escribirla, no un escaneo automático de rutas de archivo modificadas. Un cambio en una biblioteca compartida puede producir una entrada distinta en cada paquete que depende de ella, y solo una persona puede decidir qué debe decir realmente cada una de esas entradas derivadas.

¿Debería un monorepo usar un único número de versión para todo? Solo si cada paquete siempre se lanza junto con los demás. Si los paquetes alguna vez se publican de forma independiente, necesitan versiones independientes, y las versiones independientes necesitan changelogs independientes para tener sentido.

¿Una herramienta de changelog para monorepo reemplaza el paso de edición humana? No. Herramientas como Changesets automatizan recopilar y ensamblar notas por paquete en el momento del lanzamiento; la nota en sí, escrita en el lenguaje del lector en vez del de quien contribuye, sigue siendo trabajo de una persona, igual que en cualquier otra pipeline de changelog.


Las afirmaciones técnicas de este artículo no se han revisado de forma independiente. Si algo está mal, avísanos y lo corregiremos.

Relacionado en changeloop: Generador de changelog, Documentación para desarrolladores

changeloop
El equipo que crea un changelog que cierra el círculo. Tus usuarios lo piden, tu equipo lo publica y quien lo pidió se entera.