Plantilla de Changelog
Plantilla de changelog estructurada siguiendo las convenciones de Keep a Changelog para registrar versiones del proyecto.
Resumen
Un changelog es una lista curada y ordenada cronológicamente de los cambios notables de cada versión de un proyecto. Responde a la pregunta que todo consumidor hace antes de actualizar: ¿qué se rompe o mejora si actualizo? Esta plantilla sigue las convenciones de Keep a Changelog — el estándar de facto — combinadas con Semantic Versioning para el versionado.
Cuándo Usar
- Mantienes una librería, framework o aplicación con releases versionados
- Necesitas comunicar breaking changes a los consumidores — combínala con la Plantilla de Aviso de Deprecación cuando desactives funcionalidades
- Quieres automatizar la generación de notas de release
Plantilla
# Changelog
Todos los cambios notables de este proyecto se documentarán en este archivo.
El formato se basa en [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
y este proyecto sigue [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Nueva funcionalidad
### Changed
- Cambios en funcionalidad existente
### Deprecated
- Funcionalidad que se eliminará en una versión futura
### Removed
- Funcionalidad eliminada en esta versión
### Fixed
- Correcciones de bugs
### Security
- Correcciones de vulnerabilidades
## [1.0.0] - YYYY-MM-DD
### Added
- Release inicial con funcionalidad core
Ejemplo Completo
# Changelog
Todos los cambios notables de payment-service se documentan aquí.
El formato se basa en [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
y este proyecto sigue [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Endpoint de reembolso parcial: `POST /payments/:id/refund-partial` (#456)
- Campo metadata en respuestas de pago para datos personalizados (#449)
### Changed
- El campo `amount` ahora retorna como entero en centavos en lugar de decimal (#451)
## [2.5.0] - 2026-07-15
### Added
- Autenticación con passkeys vía WebAuthn (#412)
- Exportación de datos a CSV desde el panel de administración (#389)
### Changed
- Búsqueda full-text ~3x más rápida tras añadir índices GIN en PostgreSQL (#402)
- Límite de paginación por defecto subido de 50 a 200 resultados (#407)
### Fixed
- Error 500 al crear una cuenta con un email de más de 50 caracteres (#401)
- Push notifications no entregadas en iOS 17.4+ (#405)
### Security
- Actualizado `jsonwebtoken` 2.1.0 → 2.3.0 para parchear CVE-2026-11482 (#410)
- Validación de origen para prevenir CSRF en endpoints de pago (#413)
### Deprecated
- Endpoints de API v1 — se eliminan en v3.0.0, migrar a paths `/v2/` (#390)
- Campo `user.name` — usar `user.firstName` y `user.lastName` (#395)
## [2.4.0] - 2026-06-15
### Added
- Dashboard de métricas en tiempo real (#367)
- Webhooks para eventos de pago (#372)
### Fixed
- Race condition en procesamiento de pagos concurrentes (#358)
- Memory leak en el worker de notificaciones (#361)
Categorías Explicadas
Keep a Changelog define exactamente seis categorías — mantente en ellas y no inventes nuevas:
| Categoría | Uso |
|---|---|
| Added | Nueva funcionalidad |
| Changed | Cambios en funcionalidad existente |
| Deprecated | Funcionalidad marcada para eliminación en una versión futura |
| Removed | Funcionalidad eliminada en esta versión |
| Fixed | Correcciones de bugs |
| Security | Correcciones de vulnerabilidades de seguridad |
Los breaking changes no son una categoría aparte — van bajo Deprecated (todavía funciona, con fecha de eliminación) o Removed (ya eliminado). Márcalos claramente en el texto de la entrada y repítelos al inicio de tus release notes. La Plantilla de Aviso de Deprecación cubre la parte del anuncio.
Semver y Changelog
| Cambio de versión | Entrada de changelog | Ejemplo |
|---|---|---|
| MAJOR (X.0.0) | Breaking changes bajo Removed/Changed | ## [3.0.0] - Removed: XML response format |
| MINOR (X.Y.0) | Nueva funcionalidad bajo Added | ## [2.5.0] - Added: CSV export |
| PATCH (X.Y.Z) | Bug fixes bajo Fixed/Security | ## [2.4.1] - Fixed: Login redirect loop |
Workflow de Release
Cortar un release se vuelve mecánico cuando las entradas caen en Unreleased a medida que se mergean PRs:
- Durante el desarrollo — cada PR visible para el usuario agrega una línea bajo
## [Unreleased]en la categoría correcta, con el número de issue o PR. - Al cortar el release — renombra
## [Unreleased]a## [X.Y.Z] - YYYY-MM-DDy abre una sección## [Unreleased]vacía arriba. - Tag y publicación —
git tag v2.5.0, push, y crea el release de GitHub/GitLab apuntando a la sección nueva del changelog. - Verificación — un check de CI que falle cuando un tag no tiene su heading
## [X.Y.Z]detecta olvidos.
Imponer el Changelog en CI
Un changelog que depende de la memoria muere en silencio. Dos checks baratos de CI lo mantienen honesto:
# .github/workflows/changelog.yml — exige una entrada de changelog en cada PR
name: Changelog
on: [pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- name: Verificar que CHANGELOG.md fue tocado
run: |
git diff --name-only origin/main...HEAD | grep -q '^CHANGELOG.md$' \
|| (echo 'PR is missing a changelog entry' && exit 1)
Para validar al cortar el release, busca el tag: grep -q "## \[$(git describe --tags)\]" CHANGELOG.md falla el pipeline si falta el heading de la versión. Los equipos que odian forzar a cada PR a tocar el mismo archivo deberían mirar los workflows por fragmentos (towncrier, changesets) — cada PR agrega su propio archivo bajo changelog.d/ y los conflictos de merge desaparecen.
Automatización
Generar entradas desde el historial de commits ahorra trabajo pero siempre necesita una revisión humana antes de publicar. Elige la herramienta según la forma de tu repo:
| Herramienta | Ideal para | Cómo funciona |
|---|---|---|
changesets | Monorepos JS/TS | Fragmentos Markdown por cambio que se compilan al release |
release-please | Proyectos en GitHub | Abre un PR de release que acumula entradas desde conventional commits |
semantic-release | Pipelines totalmente automatizados | Determina la versión y genera notas desde commits, sin paso humano |
auto-changelog | Proyectos simples | Renderiza el git log al formato de changelog |
Todas dependen de Conventional Commits (feat:, fix:, footer BREAKING CHANGE:) para clasificar entradas. Si los mensajes de commit son inconsistentes, ninguna herramienta rescata el resultado — impone la convención en CI o con pre-commit hooks antes de automatizar.
GitHub Releases también puede auto-generar notas desde PRs mergeados y labels (breaking, feature, bug). Trata su salida como borrador: expórtala a CHANGELOG.md y edítala para claridad en vez de pegarla cruda.
Un fragmento de changesets se ve así — un archivo por cambio, compilado en el changelog al cortar el release:
---
"@myorg/payment-service": minor
---
Add partial refund endpoint `POST /payments/:id/refund-partial`
Changelog vs Release Notes
Responden a preguntas distintas y no deberían ser el mismo documento:
| Changelog | Release notes | |
|---|---|---|
| Audiencia | Desarrolladores que consumen tu proyecto | Usuarios y stakeholders de un producto |
| Granularidad | Cada cambio notable, una línea por cambio | Highlights de un solo release |
| Ciclo de vida | Archivo append-only que vive en el repo | Publicado por release (GitHub Releases, blog) |
| Formato | Categorías de Keep a Changelog | Narrativa, capturas, guías de upgrade |
El changelog es la fuente de verdad; las release notes son la historia que cuentas desde él. La Plantilla de Release Notes cubre el formato del anuncio.
Migrar un Proyecto Existente
Cómo empezar un changelog en un proyecto que nunca tuvo uno:
- No rellenes historia. Empieza desde el próximo release con una nota arriba:
This changelog starts at v2.5.0. For earlier history see git log. - Siembra la sección Unreleased actual con lo que ya está mergeado:
git log --oneline v2.4.0..mainte da la lista cruda para curar. - Mantenlo honesto — incluye solo lo que los usuarios pueden observar. Omite refactors, tareas de mantenimiento y version bumps.
- Anuncia la convención en
CONTRIBUTING.mdpara que los colaboradores sepan que se espera una línea de changelog por PR — la Plantilla de Contributing Guide tiene un lugar para esto.
Lo que funciona
- Fecha cada release usando formato ISO 8601 (
YYYY-MM-DD) - Agrupa cambios por categoría dentro de cada release
- Enlaza a issues/PRs para que los usuarios puedan trazar la discusión detrás de un cambio
- Menciona breaking changes prominentemente — primero bajo Deprecated/Removed, luego en el anuncio del release
- Mantén una sección Unreleased arriba para cambios próximos
- Escribe entradas para humanos — un changelog no es un log de commits de git
- Una línea por cambio — los detalles van en el issue enlazado o la guía de migración
Errores Comunes
- Volcado de git log: un changelog es curado; el
git logcrudo es ilegible para usuarios - Fechas faltantes: cada versión publicada necesita su fecha
- Olvidar Unreleased: sin esa sección, las entradas se escriben de memoria al cortar el release y se pierden cosas
- Mezclar categorías: los fixes de seguridad van bajo Security, no Fixed — los usuarios escanean esa categoría primero
- Inventar categorías:
Breaking,Improved,Miscno están en la spec y rompen herramientas que parsean el archivo - Editar entradas viejas: nunca reescribas la sección de una versión publicada — las correcciones van en una entrada nueva
- Sin referencias a issues:
(#123)es contexto barato que los usuarios realmente usan
Cómo Escribir una Buena Entrada
Cada entrada es una sola línea que responde “¿qué cambió para mí?” Escríbela desde la perspectiva del lector, no del que la implementó.
| Entrada débil | Mejor entrada |
|---|---|
fix(auth): resolve token issue | Fixed: expired SSO sessions sent users into a login redirect loop (#220) |
add export | Added: CSV export for dashboard charts, up to 50k rows (#234) |
update deps | Security: updated jsonwebtoken to 9.0.2 to patch CVE-2026-0987 (#410) |
Reglas que mantienen las entradas legibles:
- Deja que el heading de la categoría indique el tipo — el texto de la entrada describe el efecto.
- Describe el impacto visible para el usuario, no la ruta del código: “faltaban headers de rate limit en respuestas 429”, no “fix header middleware”.
- Siempre referencia el issue o PR para que la entrada sea trazable.
- Para breaking changes, indica qué hacer en su lugar:
Removed: XML response format — use JSON (ver guía de migración).
Solución de Problemas
- El changelog se desincroniza de los git tags: se publicó un release pero
CHANGELOG.mdno tiene la sección. Agrega un check de CI que extraiga la versión del tag y busque## [X.Y.Z]— falla el pipeline si falta. - Unreleased está vacío al cortar el release: las entradas nunca se escribieron durante el desarrollo. Exige una línea de changelog en la plantilla de PR, o usa archivos fragmento (estilo
changelog.d/, comotowncrierochangesets) para que cada PR lleve su propio archivo de entrada. - Las entradas generadas parecen spam de commits: las herramientas reproducen
feat(auth): cosaliteralmente. Revisa el output generado antes de publicar — las entradas deben describir impacto visible para el usuario, no detalles de implementación. - Conflictos de merge en cada release: todos agregan líneas al mismo bloque
## [Unreleased]. Los archivos fragmento compilados al release eliminan la línea compartida. - Los breaking changes quedan enterrados: los usuarios los pasan por alto bajo Fixed. Pon deprecaciones y eliminaciones en sus propias categorías y repítelos en las release notes y la guía de migración.
Variantes
Changelog de librería
Para librerías y SDKs, incluye snippets de migración junto a los breaking changes y enlaza a una guía de migración. Anota la versión mínima de lenguaje o runtime que cada release requiere — los consumidores la necesitan para planificar upgrades.
Changelog de servicio interno
Para servicios internos, agrega contexto de despliegue: qué ambientes recibieron el release, qué feature flags se activaron y enlaces a dashboards. Los operadores necesitan trazar qué cambió en su entorno, no solo en el código.
Changelog de monorepo
Mantén un changelog por paquete (packages/foo/CHANGELOG.md) con herramientas como changesets que manejan el versionado por paquete. Un único changelog raíz en un monorepo mezcla cambios no relacionados y confunde a los consumidores de paquetes individuales.
Puntos Clave
- Sigue exactamente las seis categorías de Keep a Changelog; fecha cada release en ISO 8601.
- Actualiza
Unreleasedpor PR — cortar un release entonces es renombrar un heading, no arqueología. - Automatiza la generación con conventional commits, pero mantén una revisión humana.
- Los breaking changes van bajo Deprecated/Removed y merecen un destacado en las release notes.
Lectura Adicional
- Keep a Changelog — la especificación que sigue esta plantilla
- Semantic Versioning — reglas de numeración de versiones
- Conventional Commits — formato de commits que alimenta la automatización de changelogs
- Plantilla de Release Notes — el anuncio para usuarios que complementa al changelog
Preguntas frecuentes
¿Qué formato debería seguir un changelog?
Usa el formato Keep a Changelog con las seis categorías estándar: Added, Changed, Deprecated, Removed, Fixed y Security. Fecha cada release en ISO 8601 y enlaza a issues o PRs.
¿Debería incluir cada commit en el changelog?
No. Un changelog es curado, no un log crudo de git. Incluye solo cambios que los usuarios pueden ver: funcionalidades nuevas, fixes, breaking changes y parches de seguridad. Refactors internos y tareas de mantenimiento no van.
¿Qué es el versionado semántico?
Semantic Versioning (SemVer) usa el formato MAJOR.MINOR.PATCH: incrementa MAJOR para breaking changes, MINOR para funcionalidad nueva y PATCH para bug fixes. La spec de semver.org define las reglas.
¿Debería la sección Unreleased estar vacía entre releases?
No — justamente para eso sirve. Las entradas se acumulan bajo Unreleased a medida que se mergean PRs, así al cortar el release solo renombras el heading a la versión y fecha, y abres una sección vacía nueva.
¿Cómo manejo versiones pre-release?
Usa etiquetas de pre-release de semver: 1.0.0-alpha.1, 1.0.0-beta.2, 1.0.0-rc.1. Dale a cada una su propia sección con fecha y márcala claramente como pre-release para que los usuarios sepan que puede ser inestable.
¿Debería mantener entradas viejas para siempre?
Sí. El changelog es un registro histórico — alguien que actualiza de v1.0 a v3.0 necesita todos los cambios intermedios. Si el archivo se vuelve inmanejable, divídelo por major version (CHANGELOG-v1.md, CHANGELOG-v2.md) con un índice.
¿Cómo mantengo el changelog consistente entre colaboradores?
Pon una línea de changelog en la plantilla de PR y valídala en CI. Para equipos más grandes, los archivos fragmento compilados al release (towncrier, changesets) evitan conflictos de merge y hacen cumplir el formato mecánicamente en lugar de depender de la convención.
¿Puede el changelog ser totalmente automático?
Parcialmente. Herramientas como release-please o semantic-release generan borradores sólidos desde conventional commits, pero el output todavía necesita una pasada humana — las entradas generadas describen commits, no impacto al usuario. Automatiza la mecánica y conserva la revisión editorial.
Recursos Relacionados
Plantilla de CONTRIBUTING.md — Guía de Contribución
Una plantilla de CONTRIBUTING.md lista para usar en proyectos open-source e internos, con guía para mantenedores.
DocPlantilla README para Proyectos Open-Source e Internos
Una plantilla README lista para producción que puedes copiar y adaptar — con un ejemplo completo, notas por registro y checklist de revisión.
DocPlantilla de Release Notes
Plantilla de release notes que comunica cambios claramente a usuarios, operadores y stakeholders con categorías, instrucciones de upgrade e issues conocidos.
GuideGuía de Pipelines CI/CD
Una guía práctica para construir pipelines CI/CD con GitHub Actions, testing, estrategias de deployment y procedimientos de rollback.
RecipeConfigura pre-commit hooks con husky y lint-staged
Configura pre-commit hooks con husky, lint-staged y el framework pre-commit. Detectá problemas de lint, formato y seguridad antes de cada commit.
DocRunbook para Actualización de Dependencias
Un runbook paso a paso para actualizar las dependencias del proyecto de forma segura.