
El software, como todo en la vida, evoluciona. Si no actualizas tu aplicación, se quedará obsoleta y dejará de ser compatible con las últimas tecnologías. Esto puede afectar a su rendimiento, seguridad y usabilidad.
El mantenimiento de tu aplicación web te permite:
- Implementar nuevas funcionalidades
- Mejoras de rendimiento
- Adaptarte a nuevos dispositivos
- Ofrecer una mejor expericia de usuario
Cuando compramos un coche hemos interiorizado, como algo normal, llevarlo a revisiones y cambiar, cada cierto tiempo, algunos de sus elementos: aceite, ruedas, amortiguadores, etc. Pero no siempre lo vemos con los mismos ojos cuando se trata de la web de nuestro negocio.
El mantenimiento web muchas veces es entendido como un gasto adicional de nuestros desarrollos, pero es al contrario: es una inversión.
Nuestra web debe ser nuestro medio principal de comunicarnos con el mundo, así que requiere de una pequeña puesta a punto cada cierto tiempo.
A veces, eso no es posible o bien el anterior proveedor del servicio no lo realizó con la diligencia adecuada, por lo que el desarrollo se puede haber quedado obsoleto.
En estos casos, lo más importante es tener clara la tarea a realizar y elegir entre una actualización o una migración a las versiones más recientes del software.
En muchos casos, ambas opciones estarán condicionadas por motivos externos, como módulos que no funcionan con determinadas versiones o la obligatoriedad de adaptarnos a nuevos estándares de seguridad.
Esta tarea, se complica un poco más cuando se trata de grandes aplicaciones que utilizan un framework de desarrollo que se mantenga en constante evolución.
Los nuevos frameworks de desarrollo liberan versiones a un ritmo vertiginoso. Hubo un tiempo en el que había incluso varias versiones cada año.
Migrando un desarrollo Laravel
Desde la liberación de la versión 8 de Laravel en septiembre de 2020 se estableció un calendario de versiones en el que se limitaban las versiones mayores a una por año, con una liberación casi semanal de una versión menor.
Esto, que podría ser una buena noticia, también tiene su parte negativa. Necesitamos actualizar nuestro software en el primer trimestre de cada año para no quedarnos atrás en cuanto a funcionalidades y sobre todo, vulnerabilidades de seguridad.
Crear una aplicación con un framework en el que prima la configuración puede ser relativamente complejo, pero una vez que logramos adaptarnos y conocemos esos parámetros que cambian el comportamiento global, es un desarrollo muy fluido.
Cuando se libera la nueva versión y queremos actualizar nuestro software, muchas veces nos encontramos con múltiples avisos y errores que nos llevan a desistir de esta transición, provocando que tengamos un software obsoleto.
Para evitar caer en la tentación, debemos migrar tan pronto como sea posible nuestras aplicaciones para que los cambios sean de menor calado y poder realizarlos con garantías.
Y como el mundo del desarrollo no se parece en nada al mundo perfecto, vamos a ponernos en una situación en la que tenemos que migrar una aplicación y no es entre dos versiones consecutivas.
Artículo recomendado: por qué es un buen momento para aprender Laravel
Manos a la obra
Vamos a migrar una vieja aplicación que lleva un tiempo sin mantenimiento, algo más de un año. Pero en esos meses, hay un salto grande de versiones, concretamente desde la 9 a la 11.
Partimos de nuestra aplicación en la versión 9. Hacemos una copia y empezamos a migrar según nos indica la lógica de composer y php: cambiamos la versión de laravel/framework a la versión 11 y ejecutamos la actualización de paquetería con composer
composer update
Y aquí empieza una lista interminable de errores.
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Conclusion: don't install laravel/framework v11.0.0 (conflict analysis result)
- Conclusion: don't install laravel/framework v11.0.1 (conflict analysis result)
- Conclusion: don't install laravel/framework v11.0.2 (conflict analysis result)
- Conclusion: don't install laravel/framework v11.0.3 (conflict analysis result)
- Conclusion: don't install laravel/framework v11.0.4 (conflict analysis result)
- Conclusion: don't install laravel/framework v11.0.5 (conflict analysis result)
- Conclusion: don't install laravel/framework v11.0.6 (conflict analysis result)
- Conclusion: don't install laravel/framework v11.0.7 (conflict analysis result)
- Conclusion: don't install laravel/framework v11.0.8 (conflict analysis result)
- Conclusion: don't install laravel/framework v11.1.0 (conflict analysis result)
- spatie/laravel-ignition[1.5.0, ..., v1.x-dev] require illuminate/support ^8.77|^9.27 -> satisfiable by illuminate/support[v8.77.0, ..., 8.x-dev, v9.27.0, ..., 9.x-dev].
- spatie/laravel-ignition[1.0.0, ..., 1.4.1] require illuminate/support ^8.77|^9.0 -> satisfiable by illuminate/support[v8.77.0, ..., 8.x-dev, v9.0.0-beta.1, ..., 9.x-dev].
- Only one of these can be installed: illuminate/support[v6.0.0, ..., 6.x-dev, v7.0.0, ..., 7.x-dev, v8.0.0, ..., 8.x-dev, v9.0.0-beta.1, ..., 9.x-dev, v10.0.0, ..., 10.x-dev, v11.0.0, ..., 11.x-dev], laravel/framework[v11.0.0, ..., 11.x-dev]. laravel/framework replaces illuminate/support and thus cannot coexist with it.
- Root composer.json requires laravel/framework ^11 -> satisfiable by laravel/framework[v11.0.0, ..., 11.x-dev].
- Root composer.json requires spatie/laravel-ignition ^1.0 -> satisfiable by spatie/laravel-ignition[1.0.0, ..., v1.x-dev].
Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.
Lenguaje del código: PHP (php)
Normalmente junto con una versión de framework, también se necesita la actualización de más paquetes. Y eso es lo que nos están trasladando los mensajes anteriores.
Por suerte, al final, composer no da una pista
Siguiendo el consejo, volvemos a intentar realizar la misma acción con el modificador –with-all-dependencies
composer update --with-all-dependencies
Lenguaje del código: JavaScript (javascript)
Y mismo resultado.
En unos casos serán funcionalidades que están ahí disponibles y que no utilizamos, por lo que podríamos eliminarlos. Pero en la mayor parte de las aplicaciones de cierta complejidad resolverán tareas imprescindibles para el correcto funcionamiento de nuestra aplicación, por lo que eliminar no es una opción.
En la aplicación que estamos migrando hay un problema con las versiones de ignition, un paquete que utilizamos principalmente para depuración de errores. Podríamos probar a eliminarlo, pero haría más complejo nuestro mantenimiento.
Pasos para realizar la migración
Nuestra idea inicial nos puede llevar a pensar que lo más rápido es hacer una migración completa a la última versión y posteriormente corregir los fallos que surjan.
En este caso, sería un gran error, puesto que nos meteríamos en una maraña de dependencias y modificaciones cuando se trate de un salto grande entre versiones, así que iremos paso a paso.
De versión 9 a versión 10
Lo primero que tenemos que hacer ver las necesidades para migrar a la siguiente versión mayor de nuestro código, en nuestro caso, la 10.
Dentro de la documentación que ofrece Laravel en su página oficial, tenemos un apartado para la actualización a cada versión mayor
https://laravel.com/docs/10.x/upgrade
En ese documento nos indican una serie de versiones que debemos modificar en nuestra paquetería dentro del fichero composer.json
Adicionalmente, nos pide un cambio en la clave “minimum-stability” al valor «stable». Esta clave se encuentra casi al final del fichero y sirve para indicar el tipo de paquetería que admitimos. Como nuestro objetivo es llevarla a una versión superior, debemos utilizar las versiones estables de cada paquete, que son las que se trasladarán a la siguiente versión del framework.
Normalmente, este cambio lo habremos realizado cuando llevamos nuestra aplicación a producción la primera vez, pero por si acaso partimos de una rama que no tiene la configuración de despliegue, es mejor revisarlo.
Y ahora sí, ejecutamos
composer update --with-all-dependencies
Lenguaje del código: JavaScript (javascript)
Esperamos unos segundos, en los que ya no aparecen mensajes de alerta. Y listo!
Ya tenemos la mitad del camino, ahora solamente hay que repetir con la migración de versión 10 a la 11
De versión 10 a versión 11
En nuestro caso, si lanzamos la actualización de paquetes con composer vuelve a presentar los errores del principio porque utilizamos laravel-sanctum, que es un paquete que ha tenido un cambio importante en su gestión y por ello tiene un apartado específico en la guía de migración.
https://laravel.com/docs/11.x/upgrade#sanctum
En el caso del paquete Sanctum, debemos realizar unos cuantos pasos adicionales.
Este paquete proporciona una forma simple de autenticar determinadas aplicaciones (principalmente las de una sola página) y para securizar nuestras API’s.
En la versión 11 de Laravel, Sanctum se integra con el sistema de autenticación nativo por lo que cambia su configuración.
Siguiendo las indicaciones del documentoPublicamos el paquete según nos indica
php artisan vendor:publish --tag=sanctum-migrations
Y vamos a la configuración de la clave middleware, modificando los valores de las dos entradas existentes y añadiendo la nueva entrada para la validación del token csrf
'middleware' => [
'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class,
'encrypt_cookies' => Illuminate\Cookie\Middleware\EncryptCookies::class,
'validate_csrf_token' => Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class,
],
Lenguaje del código: PHP (php)
En nuestro caso, no utilizamos ninguno de los restantes paquetes que tienen un cambio en su comportamiento que obliga a cambiar la configuración, por lo que ignoramos el resto de indicaciones
Pero si tuviéramos algún paquete más en la misma situación que Sanctum, seguiríamos los mismos pasos.
Y una vez hechos los cambios de versión que nos indica y ahora sí, se actualiza toda la paquetería.
A probar
Tras terminar la actualización de la paquetería, no deberíamos tener ningún fallo en nuestra aplicación, salvo que hayamos tenido un errores o warning durante la actualización. No obstante, no está de más realizar unas pequeñas pruebas de usuario.
Salvo que tengas una aplicación muy simple o unas pruebas automatizadas muy básicas, tus testsuites tendrán algunos errores (menores), que te impedirán lanzarlas directamente.
Así que mi recomendación es realizar un pequeño repaso manual (a la vieja usanza) y tras verificar que las principales funcionalidades de bases de datos, comunicaciones, permisos, almacenamiento, etc., se ejecutan sin problemas, modificamos las pruebas automatizadas que sean necesarias y validamos que todo está en orden.