Ingeniería

Semantic versioning y tu changelog

5 min de lectura

Semantic versioning le dice a quien llama cuánto puede dolerle un lanzamiento antes de leer una sola entrada del changelog. Pasar de 2.4.1 a 2.5.0 dice: nueva capacidad, nada se rompe. Pasar de 2.5.0 a 3.0.0 dice: lee esta entrada antes de actualizar. El changelog y el número de versión están pensados para afirmar lo mismo en dos formatos, y la mayor parte de la fricción entre ambos aparece justo cuando no coinciden, lo cual pasa más a menudo de lo que la especificación sugeriría.

¿Qué promete realmente cada número de una versión?

Semantic versioning define tres números, MAJOR.MINOR.PATCH, cada uno con una regla estricta sobre qué lo activa. Un salto MAJOR significa un cambio incompatible: algo que una integración correcta y existente podría notar y por lo que tendría que cambiar. Un salto MINOR significa nueva funcionalidad compatible hacia atrás: nada existente se rompe, algo nuevo está disponible. Un salto PATCH significa un arreglo compatible hacia atrás: el comportamiento se acerca más a lo documentado, y nadie que dependiera del comportamiento anterior a propósito debería notar nada.

SaltoSignificadoLa entrada debería leerse como
MAJOR (1.x.x -> 2.0.0)Un cambio incompatible“Esto requiere acción antes de actualizar”
MINOR (1.2.x -> 1.3.0)Nueva capacidad compatible“Esto ya está disponible, nada más cambió”
PATCH (1.2.3 -> 1.2.4)Un arreglo compatible“Esto ahora se comporta como estaba documentado”

La tabla también sirve como prueba a la inversa: si una entrada no se lee como su fila, o el número de versión está mal, o la entrada está vendiendo de más o de menos lo que realmente pasó.

¿Qué cuenta como cambio incompatible a efectos de versionado?

La misma prueba que decide si algo pertenece a un changelog de API: si una llamada correcta, escrita contra el comportamiento anterior y sin tocar desde entonces, podría comportarse distinto por este cambio. Qué es un cambio incompatible y cómo lanzarlo cubre la decisión al completo, incluidos los casos que parecen incompatibles y no lo son, y los que parecen pequeños y no lo son. En resumen para el versionado: si la respuesta es sí, el salto es MAJOR sin importar cuánto código haya tocado internamente el cambio. Los números de versión siguen la consecuencia para quien llama, no el esfuerzo del equipo.

¿Cómo debería relacionarse una entrada de changelog con un salto de versión?

Una entrada, una categoría de salto, dicha desde el principio. El patrón de la tabla continúa directamente: una entrada incompatible va bajo la versión que la introdujo, redactada primero como advertencia y después como descripción. Una entrada aditiva va bajo su versión MINOR, redactada como disponibilidad. Un arreglo va bajo su versión PATCH, redactado como corrección. Mezclar categorías en una entrada, como meter un cambio incompatible en el mismo párrafo que un arreglo sin relación, es la forma en que una lectora se pierde justo lo único que realmente importaba.

## 3.0.0 (2026-09-07)

### Changed
- **BREAKING:** `GET /reports` ahora devuelve los importes como
  enteros en la unidad monetaria más pequeña (centavos) en lugar de
  decimales. Actualiza cualquier código que lea `amount` directamente.

## 2.9.0 (2026-09-01)

### Added
- Los informes ahora se pueden filtrar por `status`.

## 2.8.4 (2026-08-28)

### Fixed
- `GET /reports?status=` devolvía una página vacía en vez de un 400
  para un estado desconocido.

Leído de arriba abajo, el número de versión y la etiqueta de sección dicen lo mismo dos veces, y ese es justo el objetivo: una lectora que solo repasa los encabezados obtiene una lectura de riesgo correcta antes de abrir una sola línea.

¿La regla de cambio incompatible aplica igual antes de la 1.0.0?

No, y aquí es donde viene la mayor parte de la confusión sobre “eso fue realmente incompatible”. SemVer es explícito en que la versión mayor cero, 0.y.z, es para desarrollo inicial: cualquier cosa puede cambiar en cualquier momento, y la API pública no debería considerarse estable. Un salto de 0.4.0 a 0.5.0 puede llevar un cambio incompatible sin violar la especificación, porque la garantía de versión mayor solo empieza en cuanto un proyecto lanza 1.0.0. Una entrada de changelog sigue debiéndoles a las lectoras la misma honestidad sobre qué se rompió; lo único que cambia es que el número de versión en sí no es la señal en la que confiar antes de que llegue la 1.0.0.

¿Y si tu producto no lanza versiones discretas?

La mayoría de los productos SaaS despliegan de forma continua y nunca muestran un número de versión a quien llama, lo que no elimina la necesidad de esta disciplina, solo el número que normalmente la llevaría. La entrada de changelog tiene que hacer todo el trabajo sola: decir con claridad si un cambio es incompatible, aditivo o un arreglo, con las mismas tres palabras que usa semantic versioning, incluso sin un campo de versión al que atarlas. Algunos equipos mantienen una versión puramente interna solo para anclar entradas de changelog a algo enlazable, sin mostrarla nunca directamente a quien llama.

¿Cómo se aplica esto específicamente a un changelog de API?

De forma más estricta que en casi cualquier otro sitio, porque quienes llaman a una API son código, no personas que puedan encogerse de hombros ante un cambio inesperado. Changelog de API: qué publicar y quién lo lee cubre la forma completa de ese documento; la disciplina de versionado aquí es lo que mantiene honestas sus secciones de cambios incompatibles y aditivos. Una API que ofrece varias versiones a la vez, como v1 y v2 servidas en paralelo durante una ventana de migración, está aplicando semantic versioning en la práctica a escala de toda la interfaz en lugar de un solo paquete, y el mismo vocabulario de tres palabras sigue aplicándose a cada entrada.

¿Qué dice Keep a Changelog sobre el versionado?

Se vincula directamente por nombre con semantic versioning y recomienda el mismo vocabulario de categorías que usa este artículo: Added, Changed, Deprecated, Removed, Fixed, Security. Keep a Changelog, en la práctica recorre cómo adoptar esa especificación, incluidos los puntos donde los equipos suelen desviarse. La coincidencia no es casualidad: ambas especificaciones intentan resolver el mismo problema desde extremos opuestos, una estandariza el número de versión y la otra la entrada que lo explica.

FAQ

¿Necesita toda entrada de changelog un número de versión? Si el producto lanza versiones, sí, porque el número permite a una lectora saltar directamente a “cuánto me afecta esto” sin leer la entrada primero. Si el producto despliega de forma continua sin campo de versión, la redacción de la entrada tiene que llevar esa señal sola.

¿Cuál es la diferencia entre un salto MAJOR y una entrada de cambio incompatible? Deberían ser el mismo evento descrito de dos formas. El número de versión es la señal legible por máquinas (las herramientas de quien llama pueden reaccionar a ella); la entrada de changelog es la explicación legible por humanos de qué cambió concretamente.

¿Puede un lanzamiento PATCH ser incompatible? Por definición no debería. Si aun así se publicó uno, no edites ni vuelvas a etiquetar la versión publicada: la FAQ de SemVer dice que publiques una nueva versión que restaure la compatibilidad, o una nueva MAJOR si la ruptura se queda, y que documentes la versión problemática para que los usuarios sepan saltársela.

¿Necesitan los cambios puramente internos un salto de versión? No. Semantic versioning sigue la interfaz pública. Una refactorización sin efecto observable para quien llama no necesita salto ni entrada de changelog, aunque haya sido trabajo de ingeniería importante.


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.