Migrar configuraciones de tema de Discourse

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 sus configuraciones sin problemas. Esta función garantiza que las actualizaciones de los temas no interrumpan las instalaciones existentes al manejar 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 el tipo o el nombre de la configuración se cambia en el archivo settings.yml sin una migración acompañante, las instalaciones existentes donde la configuración se ha modificado desde el valor predeterminado perderán el cambio que han realizado en la configuración y potencialmente fallarán cuando se actualice el tema.

Para garantizar una transición fluida al actualizar la configuración de un tema, los desarrolladores de temas deben incluir una migración que instruya a Discourse core sobre 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-migracion.js. El prefijo XXXX es un número de versión, que comienza desde 0001 y se 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, limitada a caracteres alfanuméricos, guiones y con una longitud inferior a 150 caracteres. 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, matrices, mapas, etc., están disponibles para que las usen las migraciones. La única expectativa de Discourse core 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 del tema modificadas y devuelve un objeto Map que refleja el estado final deseado de todas las configuraciones.

Ejemplos

Renombrar una configuración de tema:

// nombre del archivo: 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:

// nombre del archivo: 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;
}

De manera 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 tipo enum:

// nombre del archivo: 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;
}

Agregar un nuevo elemento a una configuración de lista:

// nombre del archivo: 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 una migración se modifica después de una ejecución exitosa, no se volverá a ejecutar. 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. Sugiera cambios en github.

8 Me gusta