ServiceProvider, VendorPublishCommand y Migrator de Laravel 13. La implementación del framework que se toma como referencia es v13.34.0.
¿Copiar los archivos o cargarlos desde el paquete?
publishesMigrations() solo registra el origen y el destino de la copia como recursos publicables. Arrancar el provider no copia archivos ni ejecuta SQL.
Por su parte, loadMigrationsFrom() registra una ruta de búsqueda en el Migrator. Con un migrate normal, los archivos de esa ruta también se incluyen, pero arrancar el provider por sí solo no los ejecuta.
Si el diseño espera que el usuario ajuste nombres de tablas o columnas antes de ejecutar, la publicación es la opción candidata. Si el paquete gestiona el esquema y no se espera que el usuario edite los archivos, también puedes considerar la carga directa. Los dos ejemplos de provider siguientes son alternativas entre sí.
Implementar la publicación
Asigna una etiqueta propia del paquete para que el usuario pueda publicarlo por separado de otros recursos.El cambio de marca de tiempo depende de la configuración
La documentación oficial describe que, al publicar, la marca de tiempo de la migración se actualiza a la fecha y hora actuales. Sin embargo, la implementación deServiceProvider::publishesMigrations() solo añade el origen a los archivos cuya marca de tiempo se actualizará cuando database.migrations.update_date_on_publish está activado. El valor por defecto al leer esta configuración es false.
En la aplicación estándar de Laravel 13, config/database.php incluye la siguiente configuración. En aplicaciones que heredan una estructura antigua, comprueba también que esta configuración exista.
VendorPublishCommand reescribe la fecha cuando el archivo coincide con la ruta real de un origen registrado y el nombre de destino tiene el formato YYYY_MM_DD_HHMMSS_. Toma como base la hora de inicio del comando y suma un segundo por cada archivo afectado. Si el nombre no tiene este formato, ese proceso no le añade ninguna fecha.
La actualización de la marca de tiempo depende tanto del registro en el paquete como de la configuración de la aplicación que lo usa. No cambies esta configuración de forma generalizada desde el provider del paquete; documenta el requisito en las instrucciones de instalación. Si se usa la caché de configuración, también hay que reconstruirla después de cambiar la configuración.
Volver a publicar no significa “añadir solo lo pendiente”
vendor:publish no consulta el historial de ejecución de la base de datos. Además, en el proceso de copia de v13.34.0, la comprobación de archivos existentes se hace sobre el destino antes del cambio de marca de tiempo. Incluso al publicar un directorio, primero comprueba si en el destino existe la misma ruta relativa que en el origen, y solo después reescribe la fecha.
Por eso, si la fecha cambió en la primera publicación y en la aplicación no existe un archivo con el mismo nombre que el origen, volver a publicar la misma etiqueta puede añadir otro archivo con una fecha distinta. No des por hecho que, sin --force, siempre se evitan los duplicados.
Si una migración ya se ejecutó se decide por el nombre de archivo
Migrator::getMigrationName() devuelve el nombre base del archivo sin .php. Para determinar qué está pendiente, compara este nombre con el historial de ejecución. No decide en función de si el contenido PHP o el nombre de la tabla son iguales.
Implementar la carga directa
Si quieres que las migraciones del paquete se ejecuten tal cual, registra la ruta de búsqueda. Con este método no se añade ningún proceso que publique los mismos archivos.loadMigrationsFrom() llama a path() cuando se resuelve el Migrator. Migrator::path() elimina las rutas de búsqueda duplicadas, y getMigrationFiles() indexa los archivos encontrados por nombre de migración y los ordena por ese nombre.
Cuando el usuario actualiza el paquete, los archivos nuevos se incluyen en el siguiente migrate. No cambies el nombre de los archivos existentes y añade archivos nuevos para los nuevos cambios de esquema. Para evitar colisiones con otros paquetes, incluye también el nombre de la funcionalidad, como en create_courier_deliveries_table. Los archivos con el mismo nombre comparten la misma clave, así que no se ejecutan ambos de forma independiente.
Hacer llegar los cambios de esquema a los usuarios existentes
Por ejemplo, para añadir un número de seguimiento a la tabla de envíos, no edites elcreate_courier_deliveries_table ya publicado: añade un archivo nuevo para el cambio. Si editas la migración de creación existente, ese cambio no se ejecutará para los usuarios que ya la ejecutaron.
database/migrations/2026_10_02_000000_add_tracking_code_to_courier_deliveries_table.php
Qué comprobar antes de publicar una versión
Además de las pruebas de base de datos del paquete, comprueba los procedimientos de publicación y actualización en una aplicación que lo use. Cargar las migraciones directamente en las pruebas no equivale a verificar la publicación, en la que cambian los nombres de archivo.- Una instalación inicial en una base de datos vacía crea las tablas necesarias.
- Al actualizar desde la base de datos y el historial de ejecución de una versión anterior, solo se aplican los cambios nuevos.
- Revisa la lista de archivos tras repetir el mismo comando de publicación y comprueba que el procedimiento de actualización no genera duplicados.
- El procedimiento tiene en cuenta si la actualización de fecha está activada o desactivada y si se editaron los archivos publicados.
- Comprueba el rollback de las nuevas migraciones y su orden de ejecución respecto a las demás migraciones de la aplicación.
Páginas relacionadas
Migraciones
Repasa los fundamentos de la definición de esquemas, el historial de ejecución y los rollbacks.
Pruebas de paquetes
Prueba el service provider y la base de datos del paquete.
Fusión y caché de la configuración de paquetes
Revisa procedimientos de actualización que tienen en cuenta la configuración del usuario y la caché de configuración.
Gestión de la compatibilidad de versiones
Vincula los procedimientos de actualización y los cambios de compatibilidad con la política de versiones.
Fuentes primarias consultadas
- Documentación oficial de Laravel: migraciones de paquetes
- ServiceProvider: registro de recursos publicables y rutas de búsqueda
- VendorPublishCommand: copia y cambio de marcas de tiempo
- Migrator: detección de archivos y determinación de pendientes
- Aplicación estándar de Laravel 13: configuración de base de datos