2.5 Versión 1.2.3

2.5 Versión 1.2.3

Capítulo publicado el 28/3/2022 por Enric Caumons Gou (@caumons)
  • 12 min de lectura

Para muchas personas las actualizaciones de software son como una caja negra con unos numeritos separados por puntos y, algunas veces, con algún nombre que queda bien (vende más) desde el punto de vista marketiniano. Realmente, estas actualizaciones contienen modificaciones en el código fuente y/o en los recursos usados, como: imágenes, iconos, fuentes de letra, etc. Aprovecho para recordarte la importancia de hacer copias de seguridad antes de instalar actualizaciones grandes. Más vale prevenir que curar, estás avisado.

Hay varios tipos de actualizaciones. Principalmente podemos destacar los siguientes:

  • Añaden nuevas funcionalidades: estas suelen ser las más esperadas por los usuarios y aportan valor nuevo porque ahora podremos hacer más cosas con el software, es decir, «le han añadido cosas».
  • Mejoran funcionalidades existentes: este tipo de actualizaciones puede aportar mucho valor a los usuarios debido a que tienen la capacidad de influir notablemente en el uso de las aplicaciones. Estos cambios no están centrados en solucionar errores, sino en mejorar (optimizando u ofreciendo mayor calidad o rendimiento) la forma de hacer las cosas. Algunos ejemplos son: reducción del consumo energético (alarga la autonomía de la batería), reducción del consumo de datos, reducción del espacio de almacenamiento requerido, mejora de la rapidez de ejecución, etc.
  • Eliminan funcionalidades o compatibilidades: en ocasiones hay funcionalidades demasiado costosas de mantener o que dejan de usarse porque se vuelven obsoletas o aparecen mejores alternativas. Este tipo de actualizaciones permite limpiar y simplificar el código de las aplicaciones, además de las aplicaciones en sí, dejando solo lo realmente importante. Pueden tener una afectación muy directa en los usuarios finales porque ya no podrán usar las funcionalidades eliminadas o perderán compatibilidad con las versiones a las que ya no se ofrezca soporte. Normalmente, las versiones no soportadas suelen ser antiguas, así que, si te ves afectado, quizás haya llegado la hora de actualizar tu sistema o incluso renovarlo, en vez de quedarte estancado en el pasado usando versiones prehistóricas.
  • Cambios de diseño y usabilidad: estas son las actualizaciones de chapa y pintura. Incluyen los cambios de colores, iconos, fuentes de letras, estructura de la interfaz, etc. Este tipo de cambios no siempre suelen gustar y al principio pueden conllevar rechazo por parte de los usuarios porque «les han movido las cosas de sitio y ahora no encuentran nada», con lo cual, hay que ir con mucho cuidado con hacer cambios drásticos. En caso de cambios muy radicales, a veces se ofrece la opción de usar el software tanto con el «diseño clásico» como con la nueva interfaz.
  • Refactorización de código: estos cambios no suelen aportar valor al usuario, pero sí suelen mejorar la salud mental de los desarrolladores. Es decir, se hacen cambios internos en el código para que esté mejor estructurado, sea más simple, coherente, eficiente y no haya componentes repetidos; en definitiva, para que sea más mantenible. Gracias a todo esto, se pueden ahorrar muchos futuros problemas. Una refactorización bien hecha te puede ayudar a conciliar mejor el sueño en un futuro no muy lejano.
  • Solucionan problemas: estas actualizaciones son muy comunes y suelen publicarse después de los otros cinco tipos de actualizaciones. Aunque, en ocasiones, también se requieren después de actualizaciones que igualmente solucionaban problemas porque estas introdujeron algún error nuevo, no los solucionaron completamente o destaparon errores latentes. Dicho de otra manera, cuando se producen cambios, es muy probable que surjan problemas no contemplados a priori, a pesar de que se hayan hecho pruebas de todo tipo. A veces incluso se introducen «regresiones de software», es decir, bugs que rompen cosas que funcionaban bien antes de aplicar los cambios y esto obliga a hacer nuevas actualizaciones para restablecer la normalidad lo antes posible. Las actualizaciones de corrección de errores pueden subsanar problemas de rendimiento, bloqueos, comportamientos extraños, incompatibilidades, etc. Dependiendo del tipo de incidencias que solucionen, pueden aportar mucho valor a los usuarios o pasar desapercibidas porque no tienen impacto en el usuario final. Dentro de este tipo de actualizaciones también podemos incluir los importantes parches de seguridad.

Por supuesto, una actualización puede ser de más de un tipo, ya que, por ejemplo, puede corregir errores e introducir nuevas funcionalidades al mismo tiempo.

Versionado semántico

En muchas ocasiones, las versiones suelen estar identificadas mediante números separados por puntos «.», que se leen de izquierda a derecha. En el versionado semántico se usan tres números separados por puntos del tipo X.Y.Z, donde X es el número que identifica la versión mayor, Y identifica la versión menor y Z identifica la versión del parche. De esta forma, cuando se publican versiones que arreglan bugs se incrementa la Z, cuando se publican cambios compatibles hacia atrás se incrementa la Y, por último, cuando se trata de cambios incompatibles con versiones anteriores (suelen ser cambios grandes), entonces se incrementa la X.

Dicho esto, el riesgo ordenado de menor a mayor a la hora de aplicar las actualizaciones va desde las que solo cambia la versión del parche (Z), hasta las actualizaciones entre versiones mayores (X), que son potencialmente muy problemáticas.

A la hora de actualizar dependencias de proyectos que se encuentran en fase de mantenimiento y sin el presupuesto suficiente como para implementar nuevos evolutivos, o bien cuando las actualizaciones completas implicarían cargas de trabajo muy elevadas o inasumibles (principalmente debido a cambios de versión mayores), suelen aplicarse una serie de estrategias basadas en el versionado semántico para actualizarlas solo parcialmente. Además, hay que tener en cuenta que, a veces, los procedimientos necesarios para llevar a cabo ciertas actualizaciones pueden resultar tan complejos que deben ser realizados por partes y progresivamente.

Supongamos que tenemos que actualizar una librería porque en la versión actual se ha encontrado un fallo de seguridad importante o existe un error que nos está afectando. En primer lugar, intentaríamos actualizarla a la última versión disponible, pero, si esto implica uno o varios cambios de versiones mayores, puede que no sea factible debido a incompatibilidades y conflictos con otras dependencias usadas o con el código de nuestro proyecto. Así pues, otra alternativa menos agresiva consiste en actualizar a la última versión disponible dentro de la misma versión mayor que estemos usando. No obstante, hay ocasiones en las que tampoco nos será posible realizar este tipo de actualizaciones sin tener que actualizar o hacer cambios en cascada. Entonces, otra opción es actualizar hasta la versión anterior a la que introduce los cambios incompatibles con nuestro proyecto. Por último, hay casos en los que instalar la siguiente versión menor ya resulta complicado, debido también a incompatibilidades u otros problemas, y se opta por actualizar solo la versión del parche, preferiblemente hasta la última disponible para la versión menor que estemos usando. Aunque, lamentablemente, en ocasiones también podemos encontrarnos con problemas al actualizar solo la versión del parche, debido a que quizás en el pasado tuvimos que hacer algún workaround para paliar algún bug, que finalmente ha sido arreglado en la nueva versión, y ahora este apaño causa problemas. Así pues, deberemos quitarlo para que el sistema pueda funcionar correctamente. Por motivos como este, es tan importante documentar los workarounds que se han tenido que hacer en los proyectos.

Evidentemente, debemos asegurarnos de que la nueva versión a instalar solucione el problema a resolver, en caso contrario, no habremos conseguido el objetivo. Para saber qué versión nos conviene más y hasta cuál podemos actualizar con mayor seguridad sin romperlo todo, consultaremos los archivos de registro de cambios (típicamente llamados «CHANGELOG», «CHANGES» o similar). Allí suelen indicarse las distintas versiones con los cambios introducidos, los errores solucionados, las nuevas funcionalidades añadidas, así como las posibles incompatibilidades. Además, existen herramientas que sirven para comprobar la compatibilidad entre las distintas versiones de las dependencias de un proyecto y pueden sernos de gran ayuda.

Por cierto, el hecho de usar versionado semántico implica actualizar siempre la numeración de la nueva versión publicada según corresponda, aunque los cambios introducidos puedan ser mínimos o parecer triviales. En caso contrario, existirán múltiples versiones diferentes para un mismo número de versión, lo cual no tiene ningún sentido y es absolutamente perjudicial para la salud de todos. Y, por favor, no despubliques ni renombres ninguna versión en producción sin informar debidamente de los cambios con un margen de tiempo prudencial.

Arreglar errores

Por desgracia, las actualizaciones de «bug fixing» o para arreglar errores son más comunes de lo que sería deseable. Si bien es cierto que las prisas son malas y las fechas de entrega parecen adelantarse siempre en el calendario, también vale la pena decir que es imposible tener controlados absolutamente todos los casos posibles y asegurar que el software no va a fallar bajo ningún concepto.

Imaginemos el caso en el que tenemos un programa en el cual hemos invertido muchos recursos para que sea estable y resiliente. Hacemos todas las baterías de pruebas, pero llega un momento en el que hay un apagón eléctrico y el equipo se apaga bruscamente en medio de un proceso de guardado de datos en el disco duro porque no estábamos usando ninguna batería o SAI. ¡Vaya por Dios! Nos habíamos centrado en probar el software en condiciones normales, pero no habíamos tenido en cuenta que puede haber cortes en el suministro eléctrico. Con lo cual, se han corrompido los datos y ahora el programa ya no funciona como debería…

Sí, la informática es así, las cosas fallan por donde menos te lo esperas y en el momento más inoportuno. Por este motivo, en base a los errores que se van recopilando y que van reportando los usuarios, se van publicando actualizaciones para que cada vez los programas sean más robustos y fiables.

Vender actualizaciones como parches de chapuzas

Otras veces, las actualizaciones que se publican son única y exclusivamente intentos de parchear chapuzas que nunca debieron hacerse. Es decir, no entrarían dentro de la categoría de solucionar casos extremos no contemplados, sino dentro de la de intentar arreglar problemas de base.

Por ejemplo, se contrata el desarrollo de un sistema y una vez puesto en marcha se detecta que «va lento». El cliente reporta el problema y entonces la empresa que lo ha desarrollado dice que lo investigará e implementará un evolutivo para mejorar el rendimiento. Pero claro, como se trata de hacer algo nuevo (una mejora de rendimiento), entonces esto se factura aparte, cuando realmente si se hubiese hecho bien de entrada esta situación probablemente no hubiera ocurrido.

Vale la pena decir que este tipo de situaciones no siempre son por culpa de las empresas que desarrollan los sistemas, sino por exigencias de plazos de entrega inviables por parte de los clientes. Es decir, si te piden algo «para ayer», es evidente que no tendrás tiempo para pensar una buena arquitectura, ni revisar el código, ni probablemente implementar ningún test.

Por lo tanto, una vez más, se necesita de la buena fe de las dos partes, confiando en que la empresa será profesional y lo hará de la mejor forma posible, siempre teniendo en cuenta los recursos de los que dispondrá, tanto humanos como materiales, tiempo y dinero. ¡No se le pueden pedir peras al olmo!

La bola de parches

Una de las peores cosas que pueden ocurrir es que al hacer una bola de parches, uno encima del otro para intentar remendar algo que está mal de base, al final no se vea ni qué es lo que estaba mal debajo del todo y se acabe llegando a una situación completamente insostenible. En estos casos, las nuevas versiones con parches mal hechos se suceden sin parar y no se consigue llegar a una versión considerada estable. Es decir, se hacen auténticas locuras que se aguantan con pinzas y no puedes tocar nada sin miedo a que se desmorone todo el castillo de naipes.

Estas bolas de parches son como cuando empiezas haciendo una pequeña bolita de nieve, la haces rodar por encima de nieve virgen y se va haciendo cada vez más grande, hasta que puedes hacer un muñeco de nieve con ella. La diferencia principal es que las bolas de parches no se acaban convirtiendo en simpáticos muñecos de nieve, sino en auténticos engendros del mal. Otro parecido muy razonable sería el de un gremlin mojado muy cabreado.

Las bolas de parches acaban generando ingentes cantidades de deuda técnica (deuda de código). Esta deuda acarrea unos tipos de interés muy altos y, si no se pagan a tiempo (solucionando los problemas de raíz en vez de huir hacia delante), pueden acabar llevando el proyecto a la bancarrota. Quizás pienses que esto es un tanto exagerado, pero no sería la primera ni la última vez que una empresa se ha visto seriamente afectada por la deuda técnica de sus sistemas informáticos, contraída a lo largo de los años y que nunca ha sido «pagada».

A continuación, voy a hacer una analogía inspirada en la Teoría de las ventanas rotas, aunque en este contexto también la podríamos llamar «Teoría del código roto». Esta teoría dice que mantener los entornos urbanos en buenas condiciones puede provocar una disminución del vandalismo y la reducción de las tasas de criminalidad. Así pues, veamos cómo se relaciona esto con los sistemas informáticos.

Un sistema lleno de parches es como un coche lleno de abolladuras y rayadas, ya no viene de una más, total, tampoco se va a notar… En cambio, si el código está limpio, es como un coche con la carrocería impoluta, ¿verdad que duele en el alma cuando lo rozas o le dan un golpe por primera vez? Además, es habitual que las primeras ocasiones en que nos ocurre algún percance de esta índole, llevemos nuestro vehículo al taller para que arreglen los desperfectos y vuelva a estar como nuevo. No obstante, a medida que envejece o en el caso de que la aparición de desperfectos se convierta en algo recurrente; si no tomamos medidas, optamos por asumirlo y nos resignamos a tener la carrocería en mal estado y en continuo deterioro, aumentará el riesgo de que sufra actos vandálicos debido al aspecto de dejadez y abandono.

Siguiendo con la analogía, seguramente nos lo pensaremos dos veces antes de introducir el primer parche chapucero en un sistema limpio. Pero, si nos encontramos parches mal hechos, errores y problemas sin cesar, es probable que se acabe optando por añadir más apaños encima, haciendo que la bola de parches sea cada vez más grande e inmantenible. Sin embargo, el problema principal no radica en añadir unos parches más, sino en haber permitido la formación de una bola tóxica y putrefacta de parches tan enquistada en el sistema, que se acaba convirtiendo en un mal endémico muy difícil de extirpar. Dicho todo esto, no permitas que aparezcan signos de abandono en tus sistemas o, según la Teoría de las ventanas rotas, van a acabar siendo vandalizados.

Ojo con las compatibilidades

Tal y como ya he dicho, uno de los principales problemas con las actualizaciones son precisamente las incompatibilidades entre las distintas versiones. Muchas veces cuando actualizamos se rompen cosas porque dejan de ser compatibles y tenemos que hacer actualizaciones en cascada (actualizar múltiples paquetes uno detrás de otro), instalar nuevos paquetes (nuevas dependencias) y eliminar paquetes viejos obsoletos para que todo vuelva a funcionar.

Además, cuando trabajamos con software customizado, es decir, cuando ha sido personalizado o modificado por alguna razón, podemos tener problemas extra a la hora de actualizarlo, debido a que las diferencias con respecto a la versión oficial sean incompatibles con las nuevas actualizaciones que queremos instalar encima. Estas situaciones pueden ser realmente complejas de gestionar y desencallar. Por este motivo, hay que pensarlo dos veces antes de usar software no oficial modificado por vete a saber quién y con qué intenciones, e igualmente antes de realizar cambios que luego puedan dificultar o impedir futuras actualizaciones.

En algunos casos nos veremos forzados a modificar configuraciones o el código de nuestros proyectos para que sean compatibles con las nuevas versiones. A veces los cambios pueden ser triviales (renombrar algo), pero en otras ocasiones pueden obligarnos a reescribir gran parte de nuestro código. Es aquí donde se tendrá que evaluar si es viable hacer este tipo de actualizaciones o existen mejores alternativas. Quizás en el momento de desarrollar el proyecto solo había una opción y la nueva versión nos obligará a hacer muchos cambios, pero ahora hay una nueva alternativa que se integra mejor con lo que tenemos y nos ahorrará trabajo. Esto ya depende de cada caso.

Versiones que no funcionan y downgrades

A veces, intentando arreglar o mejorar algo, simplemente la fastidiamos. Esto nos pasa a todos, tanto en nuestra vida personal como profesional. Nos pasa a las personas, pero también a las empresas. Tampoco es algo exclusivo del software y, si no, que se lo digan a los fabricantes de automóviles, cuando envían cartas a sus clientes para hacer campañas a vehículos que quizás tienen más de diez años, advirtiendo de que han detectado fallos en algún componente o han mejorado algún sistema de seguridad del vehículo.

Por desgracia, he sufrido en más de una ocasión el hecho de actualizar y que se rompa el sistema. Es muy probable que tú también. De hecho, seguramente recordarás que unas décadas atrás tenías que estar reinstalando el sistema operativo periódicamente. Por suerte, hoy en día esto no es tan habitual. Aun así, sigue habiendo problemas con las actualizaciones, por ejemplo, en muchas ocasiones han retirado actualizaciones de teléfonos móviles porque provocaban altos consumos de batería, fallos de conectividad, etc.

También he sufrido en varias ocasiones errores críticos en las últimas versiones y he tenido que hacer un «downgrade», es decir, retroceder a una versión anterior instalando una versión más antigua que la que estaba usando. Por suerte, esto no suele ser lo habitual, pero créeme si te digo que, cuando llegas a la conclusión de que esta es la mejor opción, esto significa que te has peleado durante muchas horas con el problema.

Siempre he dicho que el colmo de un informático es actualizar el firmware una noche de tormenta. Lo que quiero decir con esto es que las actualizaciones de firmware son operaciones muy delicadas durante las cuales no se debe apagar el dispositivo. Por lo tanto, si funciona enchufado a la red eléctrica (sin batería), ten cuidado porque a veces se producen variaciones de tensión o incluso apagones eléctricos durante las tormentas. Así que, si no quieres tener disgustos, no te la juegues y actualízalo un día que brille el sol.

¡Únete a la comunidad para no perderte nada!

¡Quiero unirme!

¿Qué te ha parecido este capítulo?

¡Compártelo!

¡Suscríbete al feed para estar al día cada vez que se publique un nuevo capítulo!

Comprar libro

${ commentsData.total }

Todavía no hay comentarios. ¡Sé el primero!

Inicia sesión para publicar, responder o reaccionar a los comentarios.

Esta web utiliza cookies. Si continúas usándola, asumiremos que estás de acuerdo.