Escribir una entrada de changelog que explique qué cambió y qué hacer
Convierte notas de versión sin procesar en una entrada de changelog que separe los cambios de las acciones necesarias del usuario y de los pasos de verificación. Una actualización sintética de software muestra cómo hacer que una nota de versión sea útil para alguien que no realizó el cambio.
Contenido revisado 2026.09.20Incluye archivos de ejemplo
Ver el índice
La traducción se ha realizado con IA. Comprueba el código, las unidades y los valores junto con el original. La revisión por hablantes nativos de cada idioma aún no se ha completado. English
Para quién esEsta guía está dirigida a equipos que necesitan notas de versión o changelogs de proyecto que expliquen tanto qué cambió como qué deben hacer los lectores a continuación.
Preparación
Python 3.12 y un comando de terminal que inicie esa versión.
Un editor de texto que pueda guardar archivos JSON y text files en UTF-8.
Una carpeta de trabajo donde el script pueda crear una nueva carpeta dentro de outputs.
Solo se requiere la biblioteca estándar de Python: json y pathlib.
01Separar el cambio de la acción del lector
Una entrada de changelog debe responder al menos tres preguntas prácticas: qué cambió, qué debe hacer el lector y cómo puede comprobar que la actualización funcionó. Una lista de implementation details puede ser correcta y, aun así, dejar a otro miembro del equipo sin saber si debe realizar alguna acción.
Este tutorial utiliza una pequeña release sintética con tres changes. Cada change tiene un area, una description factual y una required action. Una verification list separada indica al lector qué debe comprobar después de actualizar.
02Crear notas de versión sintéticas sin procesar
La siguiente release information es sintética y fue creada específicamente para este artículo. Guárdala como release_notes.json. Describe la version 1.4.0 de una herramienta ficticia de exportación CSV.
json
{
"version": "1.4.0",
"date": "2026-09-20",
"changes": [
{
"area": "Export path",
"change": "Default CSV export folder changed from reports/ to outputs/reports/.",
"action": "Update scripts or shortcuts that expect reports/."
},
{
"area": "Config key",
"change": "Configuration key report_dir was renamed to output_dir.",
"action": "Rename report_dir to output_dir before the next run."
},
{
"area": "Validation",
"change": "Empty customer_id values now stop export instead of being written as blank cells.",
"action": "Fix blank customer_id values before rerunning failed exports."
}
],
"checks": [
"Confirm a test export appears under outputs/reports/.",
"Confirm the configuration uses output_dir.",
"Confirm a row with a blank customer_id stops with a validation error."
]
}
Hay exactamente 3 changes, 3 required actions y 3 verification checks. Como el ejemplo es sintético, estos paths, configuration names y behaviors son valores de demostración, no hechos sobre un producto real.
03Determinar manualmente la entrada de changelog esperada
La entrada debe comenzar con la version y la date. Las change descriptions deben mantenerse factuales. Las required actions deben utilizar instructions directas, y la verification debe ir separada para que los lectores distingan el trabajo de configuration de los post-update checks.
text
Version 1.4.0 - 2026-09-20
What changed
- Export path: Default CSV export folder changed from reports/ to outputs/reports/.
- Config key: Configuration key report_dir was renamed to output_dir.
- Validation: Empty customer_id values now stop export instead of being written as blank cells.
What you need to do
- Update scripts or shortcuts that expect reports/.
- Rename report_dir to output_dir before the next run.
- Fix blank customer_id values before rerunning failed exports.
Check after updating
- Confirm a test export appears under outputs/reports/.
- Confirm the configuration uses output_dir.
- Confirm a row with a blank customer_id stops with a validation error.
La entrada esperada contiene una heading line, tres section headings y nueve bullet lines: tres changes, tres actions y tres checks. Ninguna action queda oculta dentro de un párrafo que describe el change.
04Generar y validar la entrada de changelog
Guarda el script siguiente como useful_changelog.py. Valida el JSON sintético, crea el changelog text, comprueba las section y bullet counts esperadas y escribe el resultado en una nueva output folder. El JSON original solo se lee.
python
import json
from pathlib import Path
SOURCE = Path("release_notes.json")
OUTPUT_DIR = Path("outputs") / "useful_changelog_result"
OUTPUT = OUTPUT_DIR / "CHANGELOG_ENTRY.txt"
def require_text(value, name):
if not isinstance(value, str) or not value.strip():
raise ValueError(f"{name} must be a non-empty string.")
return value.strip()
def main() -> None:
if not SOURCE.is_file():
raise FileNotFoundError(f"Source file not found: {SOURCE}")
if OUTPUT_DIR.exists():
raise FileExistsError(f"Output folder already exists: {OUTPUT_DIR}")
with SOURCE.open("r", encoding="utf-8") as stream:
data = json.load(stream)
version = require_text(data.get("version"), "version")
date = require_text(data.get("date"), "date")
changes = data.get("changes")
checks = data.get("checks")
if not isinstance(changes, list) or not changes:
raise ValueError("changes must be a non-empty list.")
if not isinstance(checks, list) or not checks:
raise ValueError("checks must be a non-empty list.")
change_lines = []
action_lines = []
for index, item in enumerate(changes, start=1):
if not isinstance(item, dict):
raise ValueError(f"Change {index} must be an object.")
area = require_text(item.get("area"), f"change {index} area")
change = require_text(item.get("change"), f"change {index} description")
action = require_text(item.get("action"), f"change {index} action")
change_lines.append(f"- {area}: {change}")
action_lines.append(f"- {action}")
check_lines = [f"- {require_text(value, 'check')}" for value in checks]
lines = [
f"Version {version} - {date}",
"",
"What changed",
*change_lines,
"",
"What you need to do",
*action_lines,
"",
"Check after updating",
*check_lines,
]
text = "\n".join(lines) + "\n"
if text.count("\nWhat changed\n") != 1:
raise RuntimeError("Missing What changed section.")
if text.count("\nWhat you need to do\n") != 1:
raise RuntimeError("Missing action section.")
if text.count("\nCheck after updating\n") != 1:
raise RuntimeError("Missing verification section.")
bullet_count = sum(line.startswith("- ") for line in lines)
expected_bullets = len(changes) * 2 + len(checks)
if bullet_count != expected_bullets:
raise RuntimeError("Unexpected bullet count.")
OUTPUT_DIR.parent.mkdir(parents=True, exist_ok=True)
OUTPUT_DIR.mkdir()
with OUTPUT.open("x", encoding="utf-8") as stream:
stream.write(text)
print(f"Changes: {len(changes)}.")
print(f"Required actions: {len(action_lines)}.")
print(f"Verification checks: {len(checks)}.")
print(f"Total bullets: {bullet_count}.")
print(f"Output: {OUTPUT.as_posix()}")
if __name__ == "__main__":
main()
05Comprobar el resultado esperado
Para esta release sintética, el script debería informar de tres changes, tres required actions, tres verification checks y nueve bullet lines. La salida de consola esperada que aparece a continuación se obtuvo manualmente y no es un execution log.
Confirma que cada change aparezca una vez bajo What changed.
Confirma que cada change tenga una instruction correspondiente bajo What you need to do.
Confirma que los verification steps estén separados de las required actions.
Confirma que los paths y configuration names se copien exactamente de las synthetic source notes.
Ejecuta el script de nuevo sin cambiar OUTPUT_DIR. Debería detenerse con FileExistsError en lugar de sustituir la entrada anterior.
06Reconocer entradas de changelog técnicamente correctas pero poco útiles
Texto débil de changelog
Qué falta
Updated export logic
Los lectores no saben qué behavior cambió ni si deben actuar.
Fixed configuration
No se identifican la key afectada ni el replacement necesario.
Improved validation
La nueva failure condition y su efecto sobre los users no están claros.
Various bug fixes
No hay información sobre impact, scope ni required checks.
Please update accordingly
La action es demasiado vaga para ejecutarla o verificarla.
Evita obligar al lector a reconstruir el cambio a partir de issue trackers, commits o chat history. Si una actualización cambia un path, key, command, file format o required input, indica directamente el old y el new behavior.
07Mantener el changelog limitado a consecuencias visibles para el usuario
Una entrada de changelog no sustituye technical documentation, migration instructions, test evidence ni version control history. Los changes complejos pueden necesitar links a esos materiales, pero el changelog debe seguir resumiendo la consequence y la immediate action.
No todo internal refactor necesita una entrada de changelog. Si behavior, interfaces, dependencies, required inputs, outputs, configuration o workflow no cambian para el lector, las implementation notes detalladas pueden pertenecer a otro lugar.
Para releases más grandes, agrupa los changes relacionados por area y distingue required actions de optional recommendations. Conserva las entradas antiguas del changelog en lugar de reescribir la historia, salvo que estés corrigiendo un documented error y puedas registrar claramente esa correction.
Se contaron manualmente 3 synthetic changes, 3 corresponding required actions y 3 verification checks.
Se obtuvo manualmente la entrada de changelog esperada con tres named sections.
Se calculó el total esperado como 9 bullet lines: 3 changes + 3 actions + 3 checks.
Se comprobó que los synthetic old and new export paths sean reports/ y outputs/reports/ y que los configuration names sean report_dir y output_dir.
Se revisó el script para required text validation, section checks, bullet-count validation, output collision protection y conservación del source JSON.
Se obtuvo manualmente la salida de consola esperada.
Límites de la verificación
El código no fue ejecutado por el autor de esta respuesta; no se creó ningún changelog file.
La version, los paths, las configuration keys y el validation behavior son ejemplos sintéticos y no describen un producto real.
El script valida la structure, pero no puede determinar si una change description escrita por una persona es completa o exacta.
Las URL de la documentación oficial se proporcionaron a partir de ubicaciones de documentación conocidas, pero no se comprobaron en línea.
Las explicaciones y los ejemplos son de elaboración propia. Puedes consultar los comportamientos y conceptos relacionados en las siguientes fuentes oficiales.
En lugar de quedarse en otro resumen de la reunión, separa el trabajo acordado de los asuntos abiertos. Convierte notas sintéticas de reunión en una lista con responsables, fechas límite, entregables y evidencias de finalización, y redacta una solicitud para IA que ayude con la misma tarea.
Gestiona cada artículo como una fila y separa redacción, revisión, aprobación y publicación. Incluye la importación de un CSV local, listas desplegables, vistas de filtro, permisos de uso compartido e historial de versiones, y establece un flujo para actualizar manualmente los archivos del sitio después de la aprobación.
Define una convención sencilla de nombres de archivo para el equipo, pruébala en una carpeta sintética y crea un informe de revisión sin renombrar ni eliminar nada. El comprobador separa errores estructurales, fechas no válidas y extensiones no admitidas.
Convierte las notas de traspaso de un proyecto en una lista estructurada que registre qué debe transferirse, quién es responsable, dónde está almacenado y qué sigue sin resolverse. Un pequeño ejemplo sintético muestra cómo detectar responsables, ubicaciones y detalles de asuntos abiertos que faltan antes del traspaso.