Introducción
A partir de la versión 3.2.0.beta3 de Discourse, los temas/componentes de Discourse pueden aprovechar una función de migraciones para evolucionar y alterar su configuración sin interrupciones. Esta función garantiza que las actualizaciones de los temas no interrumpan las instalaciones existentes al gestionar los cambios en la configuración de manera controlada.
Cuándo usar migraciones
Escenarios comunes donde las migraciones son particularmente útiles:
- Cambiar el tipo de una configuración (por ejemplo, de una cadena separada por comas a una lista).
- Renombrar una configuración.
- Modificar la estructura o el formato de los datos almacenados en una configuración.
En estos escenarios, si se cambia el tipo o el nombre de la configuración en el archivo settings.yml sin una migración adjunta, las instalaciones existentes donde la configuración se ha modificado desde el valor predeterminado perderán el cambio realizado en esa configuración y potencialmente fallarán cuando se actualice el tema.
Para garantizar una transición fluida al actualizar una configuración de tema, los desarrolladores de temas deben incluir una migración que indique al núcleo de Discourse cómo migrar el estado existente que se ajusta a la versión anterior de settings.yml a la nueva versión.
Archivos de migración
Las migraciones son archivos JavaScript ubicados en el directorio migrations/settings del tema, siguiendo la convención de nomenclatura XXXX-nombre-de-la-migracion.js. El prefijo XXXX es un número de versión, que comienza en 0001 e incrementa secuencialmente, lo que dicta el orden de ejecución.
El nombre debe ser una descripción concisa del propósito de la migración, limitado a caracteres alfanuméricos, guiones y con menos de 150 caracteres de longitud. Las migraciones se ejecutan en orden ascendente según el valor numérico de sus versiones.
Recomendamos que comience con 0001 para la primera migración y 0002 para la segunda migración, etc. Tenga en cuenta que si la versión de una migración es inferior a 1000, la versión debe rellenarse con ceros iniciales para que tenga 4 dígitos, ya que el nombre del archivo de migración debe comenzar con 4 dígitos. Por la misma razón, actualmente no es posible tener más de 9999 migraciones en un tema, pero podemos cambiar eso en el futuro.
Función de migración
Las características estándar de JavaScript, como clases, funciones, arrays, mapas, etc., están disponibles para que las utilicen las migraciones. La única expectativa del núcleo de Discourse es que cada archivo de migración debe exportar una función predeterminada que sirva como punto de entrada. Esta función recibe un objeto Map que representa las configuraciones de tema modificadas y devuelve un objeto Map que refleja el estado final deseado de todas las configuraciones.
Ejemplos
Renombrar una configuración de tema:
// filename: 0001-rename-old-setting.js
export default function migrate(settings) {
if (settings.has("old_setting_name")) {
settings.set("new_setting_name", settings.get("old_setting_name"));
settings.delete("old_setting_name");
}
return settings;
}
Esta migración debe ir acompañada del cambio de nombre de la configuración en el archivo settings.yml.
Convertir una configuración de cadena separada por comas a una lista adecuada:
// filename: 0001-convert-string-setting-to-list.js
export default function migrate(settings) {
if (settings.has("list_setting")) {
const list = settings.get("list_setting").split(",");
settings.set("list_setting", list.join("|"));
}
return settings;
}
Similar al ejemplo anterior, esta migración debe ir acompañada del cambio del tipo de configuración de string a list en el archivo settings.yml.
Renombrar una opción de una configuración de enumeración:
// filename: 0001-rename-enum-choice.js
export default function migrate(settings) {
if (settings.get("enum_setting") === "old_option") {
settings.set("enum_setting", "new_option");
}
return settings;
}
Añadir un nuevo elemento a una configuración de lista:
// filename: 0001-add-item-to-list.js
export default function migrate(settings) {
if (settings.has("list_setting")) {
const list = settings.get("list_setting").split("|");
list.push("new_item");
settings.set("list_setting", list.join("|"));
} else {
settings.set("list_setting", "new_item");
}
return settings;
}
Ejecución y manejo de errores
Las migraciones se ejecutan automáticamente durante la instalación y actualización de temas. Se ejecutan solo una vez; si se modifica una migración después de una ejecución exitosa, no se ejecutará de nuevo. Si una migración falla, el proceso de actualización se detiene y se proporciona un mensaje de error sobre lo que salió mal.
Si una migración tiene un error que resulta en un estado corrupto para una configuración, la forma correcta de solucionar el problema es crear una nueva migración que corrija el estado corrupto en lugar de modificar la migración original.
Este documento está controlado por versiones: sugiere cambios en github.