¿Cómo mantener actualizadas las bibliotecas de terceros?

28

Digamos que tengo un proyecto que depende de 10 bibliotecas, y dentro del tronco de mi proyecto soy libre de usar cualquier versión de esas bibliotecas. Así que empiezo con las versiones más recientes. Luego, cada una de esas bibliotecas recibe una actualización una vez al mes (en promedio). Ahora, mantener mi tronco completamente actualizado requeriría actualizar una referencia de biblioteca cada tres días.

Obviamente, esto es demasiado. Aunque generalmente la versión 1.2.3 es un reemplazo directo para la versión 1.2.2, nunca se sabe sin probar. Las pruebas unitarias no son suficientes; si se trata de un motor de archivos / bases de datos, debe asegurarse de que funcione correctamente con los archivos creados con versiones anteriores, y tal vez viceversa. Si tiene algo que ver con la GUI, debe inspeccionar visualmente todo. Y así.

Como manejas esto? Algunos enfoques posibles:

  • Si no está roto, no lo arregles . Permanezca con su versión actual de la biblioteca siempre y cuando no note nada malo cuando la use en su aplicación, sin importar con qué frecuencia el proveedor de la biblioteca publique actualizaciones. Pequeños cambios incrementales son solo desperdicio.
  • Actualice con frecuencia para mantener el cambio pequeño. Dado que tendrá que actualizar algún día en cualquier caso, es mejor actualizarlo a menudo para que note cualquier problema temprano cuando sea fácil de solucionar, en lugar de saltar sobre varias versiones y dejar que se acumulen posibles problemas.
  • Algo en el medio. ¿Hay un punto dulce?
Joonas Pulakka
fuente
1
+1: Me pregunto si, como "búsqueda de errores", podrías tener una iteración de "Actualizar Sprint" en un proyecto. Curioso sobre las respuestas :)
Matthieu

Respuestas:

25

Estoy sorprendido, y de hecho horrorizado, por la cantidad de respuestas aquí que dicen "no actualices a menos que tengas que hacerlo". Lo he hecho, y aunque es más fácil a corto plazo, a la larga arde como el infierno. Las actualizaciones más pequeñas y frecuentes son mucho, mucho más fáciles de administrar que las grandes ocasionales, y obtienes el beneficio de nuevas funciones, correcciones de errores, etc., antes.

No creo que esta idea de que los cambios en la biblioteca sean de alguna manera más difíciles de probar que los cambios en el código. Es lo mismo: está haciendo un cambio en la base de código y necesita validarlo antes de comprometerse, y más profundamente antes de lanzar. ¡Pero ya debe tener procesos para hacer esto, ya que está haciendo cambios en el código!

Si está trabajando en iteraciones, de dos a cuatro semanas de duración, sugeriría hacer que las bibliotecas de actualización se realicen una vez por iteración, lo más pronto posible después del inicio, cuando las cosas están un poco más relajadas que justo antes de una iteración fecha límite, y el proyecto tiene más capacidad para absorber el cambio. Pídale a alguien (o un par si hace pares de programación) que se siente, vea qué bibliotecas se han actualizado e intente incorporar cada una y ejecutar una reconstrucción y prueba. Presupuesto medio día a un día para cada iteración, tal vez. Si las cosas funcionan, verifique los cambios (supongo que mantiene las bibliotecas en control de origen, como lo hacemos nosotros; no estoy seguro de cómo propagaría el cambio de forma controlada si no). Obviamente, esto será mucho más fácil si tiene pruebas automatizadas que si las pruebas son completamente manuales.

Ahora, la pregunta es qué hacer si una actualización rompe cosas: ¿pasa tiempo reparándola o la deja de lado? Sugeriría inclinarse hacia este último; si puede arreglarse en una hora, hágalo, pero si una actualización va a requerir un trabajo significativo para integrarse, créelo como su propia tarea de desarrollo, para ser estimado, priorizado y programado como cualquier otro. Lo más probable es que, a menos que traiga alguna solución o mejora crucial, la prioridad será baja y nunca lo alcanzará. Pero nunca se sabe, para cuando llegue el próximo día de actualización iterativa, el problema podría haberse solucionado solo; incluso si no, al menos ahora sabe que hay un obstáculo en la ruta de actualización, y no lo sorprenderá.

Si no está haciendo iteraciones de esa longitud, establecería algún tipo de programación independiente para las actualizaciones, no más de una vez al mes. ¿Hay algún otro ritmo de proyecto al que pueda vincularlo, como una revisión mensual del estado o una reunión de la junta de arquitectura? ¿Día de paga? Noche de pizza? ¿Luna llena? Lo que sea, debe encontrar algo mucho más corto que un ciclo de lanzamiento tradicional, porque tratar de actualizar todo de una vez cada 6-18 meses será doloroso y desmoralizador.

Huelga decir que si realiza ramas de estabilización antes de los lanzamientos, no les aplicaría esta política. Allí, solo actualizaría las bibliotecas para obtener soluciones críticas.

Tom Anderson
fuente
3
+1. Trabajé en un proyecto donde los desarrolladores aplicaron la política "si no está roto, no lo arreglen". Luego encontramos un problema con una biblioteca de terceros (relativamente menor, pero era necesaria para una nueva función), que solo se solucionó en una versión mucho más tardía, que a su vez dependía de un jvm mucho más tarde. Con el jvm posterior, encontramos problemas con otras bibliotecas de terceros, que ahora tenían que actualizarse a su vez. También tuvimos que actualizar nuestro hardware, ya que Oracle ya no tiene una jvm de 32 bits para Solaris. Fue un desastre y podría haberse evitado tan fácilmente simplemente manteniendo las cosas actualizadas.
firtydank
+1 para "aunque es más fácil a corto plazo, a la larga arde como el infierno". He experimentado ambos enfoques y, si bien muchas actualizaciones pequeñas pueden parecer una molestia, no realizar actualizaciones y luego tener que actualizar 10 bibliotecas de versiones que tienen 2 años a menudo no es posible en un período de tiempo razonable. Termina con un sistema que depende de bibliotecas desactualizadas y no mantenidas, no puede usar otras bibliotecas ya que requieren una versión más nueva de esa biblioteca que no puede actualizar y en algún momento pierde la capacidad de solucionar algunos problemas en todos.
Michał Kosmulski
@firtydank Tengo curiosidad por lo que hicieron para resolver esto después del hecho, ¿implementaron nuevas políticas? ¿Cuál fue el cambio funcional en la organización?
buddyp450
10

Yo evalúo

  • En primer lugar, busco errores que hemos generado contra esa biblioteca y veo si se han solucionado.
  • En segundo lugar, busco otras correcciones de errores en la biblioteca de las que podríamos beneficiarnos (quizás algo que sea un posible caso de esquina).
  • En tercer lugar, busco mejoras en la lib / API y luego investigo el impacto de cambiar nuestro código para utilizar eso y la compensación benfit. En el pasado, con demasiada frecuencia actualicé libs sin utilizar sus nuevas funciones, ¡realmente tonto!

Luego pongo todo eso en contra de permanecer con la biblioteca existente.

Siempre pruebe: con suerte, sus pruebas de unidad / integración asegurarán que no ocurran regresiones importantes.

Martijn Verburg
fuente
7

El principal problema con las bibliotecas de terceros es que necesita volver a probar SU aplicación cuando las actualiza, antes de que pueda entrar en producción. Por lo tanto, a menos que tenga un error reportado, que requiera actualizar una biblioteca, no los toque hasta que tenga tiempo para realizar un ciclo completo de garantía de calidad.

Esto generalmente se hace al lanzar una nueva versión.

Sin embargo, sugeriría que tenga un conjunto de pruebas para la compilación continua que le permita actualizar las bibliotecas en la rama de desarrollo y hacerlo automáticamente. Esto asegurará que descubras temprano cuando se rompe, para que puedas presentar informes de errores al proyecto.


fuente
3

Parcialmente, como se describe en svn sucursales de proveedores . El procedimiento descrito allí es muy útil, cuando sigue utilizando bibliotecas de terceros de código abierto durante mucho tiempo, y ha realizado cambios para ajustarlo a sus necesidades.

duros
fuente
2
Por favor, no solo suelte enlaces. Los enlaces tienden a desaparecer. Considere por lo menos resumir a qué se está vinculando. Si ese enlace se rompiera, ¿qué tan útil sería esto ... quizás dentro de unos años?
Tim Post
Y votado a favor :)
Tim Post
2

Pensaría en actualizar todas las bibliotecas de un proyecto justo antes o justo después de un lanzamiento. Sin embargo, esto podría salirse de control si confía en más de 10 o 15 bibliotecas, en cuyo caso algún tipo de mecanismo de comprobación de actualizaciones sería de gran ayuda. La ventaja de esto es que tiene un tiempo dedicado a probar sus bibliotecas y puede solucionar cualquier problema de una sola vez. Tampoco tiene que hacer un seguimiento constante de las actualizaciones de cada biblioteca, solo verifica un día determinado para ver si hay actualizaciones.

También iría en contra de cualquier tipo de función de actualización automática, incluso en una rama de desarrollo. Sería frustrante si en medio de mí trabajando en algo el proyecto se rompió porque una biblioteca se actualizó automáticamente, o de repente recibí advertencias de depreciación por usar una API que fue reemplazada por otra cosa.

TheLQ
fuente
2

Tienes que preguntar, ¿qué es lo que realmente quieres de la actualización? La mayoría de las correcciones de seguridad son en realidad parches triviales, en forma de reparación:

  • Desactivado por un error donde el código arbitrario se puede copiar a un espacio no utilizado en un búfer
  • Punteros colgantes, o algo más que desencadena un comportamiento indefinido pero (más bien) determinista
  • Errores que permiten algún tipo de DoS
  • Errores que accidentalmente facilitan la indagación de datos privados
  • Errores matemáticos
  • Los mantenedores tocan cosas que no deberían (error de Debian SSL, ¿alguien?)

Si revisa la mayoría de los CVE en los últimos cinco años, los parches que los arreglan suelen ser bastante triviales, si está utilizando bibliotecas abiertas, lo que espero que sea.

Luego tiene correcciones de errores reales, que probablemente desee, pero tal vez ya lo haya solucionado usted mismo. Si no está roto, no lo arregles.

Finalmente, tiene nuevas características ... y quizás características obsoletas. Debe examinar esas notas de lanzamiento y diferencias cuidadosamente. ¿Puedes usarlos, incluso si rompen una API de la que dependen muchas otras cosas? Si es así, es hora de la cirugía ... si no, elige lo que quieras y sigue adelante.

Algunos pueden estar en desacuerdo conmigo, pero me niego a usar una biblioteca sin código fuente.

Tim Post
fuente
Seguramente prefiero las bibliotecas de código abierto, pero también uso algunas bibliotecas comerciales que cuestan $ 100 sin fuente o $ 10k con fuente, así que ...
Joonas Pulakka
2

Varía dependiendo de cosas como las bibliotecas, para qué se usan, qué tan generalizadas están en su código, el costo (en términos de tiempo y dinero) de realizar la actualización, etc.

Idealmente, siempre tendrías lo último todo el tiempo, pero si la nueva versión no es compatible con versiones anteriores, ¿entonces qué? Es posible que deba archivar esa actualización para una versión futura hasta que pueda manejar el cambio con cuidado. Podría haber algún cambio sutil en el comportamiento (como "ahora necesita establecer la propiedad X antes de llamar al método Y, u obtiene una pérdida de memoria lenta") que es difícil de verificar en las pruebas.

Por otro lado, la nueva versión podría tener algunas correcciones de seguridad serias, por lo que también debe tener eso en cuenta.

Versión corta: tómalo caso por caso.

JohnL
fuente
1

Esto dependería de sus horarios de lanzamiento.

Pero mi consejo sería instalar un conjunto de bibliotecas en todas las máquinas de los desarrolladores. Considérelo un estándar de oro si desea llamarlo algo, luego comience su desarrollo para esa versión.

Solo una vez que se haya implementado la versión y esté en la fase posterior a la publicación, vuelva a evaluar sus bibliotecas, sus versiones y características. Si ofrecen algunas mejoras significativas o nuevas funciones, instálelas antes del inicio del próximo ciclo de desarrollo.

Solo instale nuevas versiones si hay un problema o error importante que deba corregirse antes de implementar el software.

Significará que se perderán algunas versiones, pero debería ahorrarle algunos dolores de cabeza y problemas de versiones que le permitirán concentrarse en desarrollar su aplicación.

GruñónMono
fuente
1

Subversión externa

Lo bueno de esa característica es que puede especificar la revisión que desea.

Tenga en cuenta que las actualizaciones serán más lentas si tiene muchos elementos externos.


fuente
En realidad los estoy usando, y son muy útiles y muy lentos X-) Pero no resuelven el problema de cuándo debo actualizar a la versión más nueva.
Joonas Pulakka
Pueden ser muy lentos, sí. Por lo general, actualizo bibliotecas externas cuando: (hay disponible una versión principal O una corrección de errores que me afecta) Y estoy en la primera mitad de la iteración.
1

Actualmente estoy configurando algo así:

  • 1 repositorio mercurial para cada extensión de mi aplicación
  • Un repositorio mercurial que reúne versiones específicas de varias bibliotecas de terceros
  • un repositorio SVN para recursos / trabajos gráficos (pero podría cambiar a otra cosa)
  • un repositorio mercurial para mi aplicación, que utiliza la función de subpositorios mercurial para usar una versión específica del repositorio de 3er pary, y algunas de las extensiones básicas

Ahora, cuando necesito trabajar en una extensión que no es "básica" (incluida implícitamente como un subrepo en el repositorio de aplicaciones), simplemente clono el repositorio en la carpeta de extensiones y dejo que CMake genere los proyectos y soluciones para toda la aplicación.

De esa manera, puedo:

  • cambie los terceros en un clon, verifique que funcione con la aplicación, insértelo en el repositorio de terceros, luego actualice la versión de subrepo del repositorio de la aplicación a la nueva versión de repositorio de terceros
  • trabajar en extensiones de forma independiente, todas juntas o simplemente elegir algunas específicas
  • no tiene que preocuparse por tener que vincular proyectos, esto lo hace Cmake simplemente escaneando los subrepos de proyectos con el repositorio de aplicaciones completo.

Todavía no tengo mucha experiencia con esta organización, pero creo que es bastante útil.

Klaim
fuente
1

Si su software es crítico para la seguridad, debe actualizarlo lo antes posible, sin excusas. No desea un pequeño error en una biblioteca de gráficos para hacer que todo su programa sea vulnerable.

De lo contrario, cuando la biblioteca está madura, es "Si no está roto, no lo arregles". para mi. Tarde o temprano, podría necesitar una función de una versión posterior y no tengo más remedio que actualizar, pero hasta entonces, el esfuerzo es difícil de justificar. Por otro lado, cuando trabajo con un lib o framework relativamente nuevo, como Grails o ExtJS, me mantengo actualizado con la última versión porque estos productos todavía no se sienten completamente maduros, por lo que es probable que la actualización me salve de encontrarse con uno de esos errores, se corrigió la versión posterior.

usuario281377
fuente
1

Uso NuGet para mantener actualizadas mis bibliotecas de terceros.

Cuando un amigo, compañero de trabajo o blog me notifica que uno de mis archivos DLL de terceros está desactualizado, NuGet hace que sea muy fácil actualizarlo.

Jim G.
fuente