Consejos para lograr la entrega "continua"

14

Un equipo tiene dificultades para lanzar software con frecuencia (una vez por semana). Lo que sigue es una línea de tiempo de lanzamiento típica:

Durante la iteración:

  • Los desarrolladores trabajan en historias sobre la cartera de pedidos en ramas de características de corta duración (esto se aplica con entusiasmo) basadas en la rama maestra.
  • Los desarrolladores con frecuencia incorporan sus ramas de funciones en la rama de integración, que se construye y prueba continuamente (en lo que respecta a la cobertura de prueba) automáticamente.
  • Los probadores tienen la capacidad de implementar automáticamente la integración en un entorno de preparación y esto ocurre varias veces por semana, lo que permite la ejecución continua de sus conjuntos de pruebas.

Cada lunes:

  • hay una reunión de planificación de lanzamiento para determinar qué historias son "conocidas" (basadas en el trabajo de los evaluadores) y, por lo tanto, estarán en el lanzamiento. Si hay un problema conocido con una historia, la rama fuente se retira de la integración.
  • no se puede integrar el código nuevo (solo las correcciones de errores solicitadas por los probadores) este lunes para garantizar que los probadores tengan una base de código estable para cortar una versión.

Cada martes:

  • Los probadores han probado la rama de integración tanto como posiblemente hayan dado el tiempo disponible y no hay errores conocidos, por lo que se corta una versión y se envía lentamente a los nodos de producción.

Esto suena bien en la práctica, pero hemos descubierto que es increíblemente difícil de lograr. El equipo ve los siguientes síntomas.

  • Se encuentran errores "sutiles" en la producción que no se identificaron en el entorno de ensayo.
  • las correcciones de último minuto continúan hasta el martes.
  • Los problemas en el entorno de producción requieren reversiones que bloquean el desarrollo continuo hasta que se logra una implementación en vivo exitosa y la rama maestra se puede actualizar (y, por lo tanto, ramificarse).

Creo que la cobertura de la prueba, la calidad del código, la capacidad de la prueba de regresión rápidamente, los cambios de última hora y las diferencias ambientales están en juego aquí. ¿Alguien puede ofrecer algún consejo sobre la mejor manera de lograr una entrega "continua"?

Ben
fuente
1
Además de la respuesta de @ emddudley sobre el libro Entrega continua, le animo a que vea infoq.com/presentations/Continuous-Deployment-50-Times-a-Day una presentación realmente interesante sobre el despliegue verdaderamente múltiple por día en vivo real producción.
sdg

Respuestas:

6
  • Se encuentran errores "sutiles" en la producción que no se identificaron en el entorno de preparación : en uno de los proyectos con tales problemas, he visto que esto se resolvió con bastante éxito mediante una táctica que llamaría problemas dobles. Quiero decir que para errores como ese, los chicos crearon dos tickets en el rastreador de problemas: uno fue asignado a los desarrolladores para corregir el código, otro a los evaluadores para diseñar y establecer una prueba de regresión o un cambio en el entorno de ensayo que evitaría repetirlo en el futuro. Eso ayudó a mantener la puesta en escena lo suficientemente cerca como para pinchar.

  • Los problemas en el entorno de producción requieren reversiones ; si son frecuentes, sus lanzamientos semanales son realmente falsos; considere ajustar la frecuencia al nivel que realmente funcione. Por falso quiero decir que si dice que una de las dos versiones de su versión semanal se revierte, significa que los usuarios se enfrentan a una nueva versión (en funcionamiento) una vez cada dos semanas, que es todo lo que cuenta, no la cantidad de veces que implementa.

  • ramas de características forzadas con entusiasmo : ¿eso significa que, hace algún tiempo, también intentó trabajar en una sola rama y la encontró inferior? En caso afirmativo, omita el resto. De lo contrario, intente trabajar en una sola rama (si es necesario, google para la estrategia de ramificación "rama de desarrollo" o la estrategia de ramificación "tronco inestable" para más detalles). O, si usa Perforce, busque en la web las pautas de Microsoft sobre ramificación y fusión. Intenta decir eso? lo siento, la palabra apropiada debe ser prueba : quiero decir, 1) planifique cuándo y cómo medir si una sola rama es mejor o no que la que tiene ahora y 2) planifique cuándo y cómo volverá a las ramas características en caso de que esto la prueba falla .


PD.

Probablemente pueda encontrar más trucos como ese buscando en la web algo como gestión de riesgos de proyectos de software


actualizar

<copia de comentarios>

Percibo que las revisiones frecuentes son un síntoma de una tubería de prueba rota, ¿no es este el caso? De cualquier manera, requieren lanzamientos repetidos para solucionar los problemas y hacer más trabajo para el equipo de operaciones. Además, las soluciones rápidas generalmente se codifican bajo una presión de tiempo extrema, lo que significa que probablemente serán de menor calidad que el trabajo normal.

</ copia de comentarios>

  • Arreglos urgentes de última hora : las preocupaciones anteriores me parecen razonables, así como su referencia a una tubería de prueba rota. Con esta actualización, la nota antes de que la nueva integración código se bloquea el lunes suena como un síntoma más de roto (creo que la palabra más precisa sería contendió ) tubería. Por contención me refiero a lo siguiente: usa una sola rama para cumplir simultáneamente dos propósitos: integración y lanzamiento. Cuando se acerca la liberación, estos dos propósitos comienzan a chocar entre sí, presionando por requisitos en conflicto: el propósito de integración se cumple mejor con una rama abierta continuamente ( Fusionar temprano y a menudo ) mientras que la liberación se beneficia de la rama sellada(aislado) el mayor tiempo posible. A-ha parece que las piezas del rompecabezas comienzan a coincidir

Mire, esa congelación del lunes ahora parece un compromiso hecho para servir a los propósitos conflictivos: los desarrolladores sufren el bloqueo de la integración de un nuevo código, mientras que los evaluadores consideran que este bloqueo es demasiado breve, todos están algo descontentos, pero ambos propósitos se cumplen más o menos.

Ya sabes, dado lo anterior, creo que tu mejor opción sería intentar liberarlo de una rama dedicada (que no sea la integración) . Ya sea que esta rama sea de larga duración como integración o de corta duración como sus ramas de características (con "característica" siendo, bueno, lanzamiento), depende de usted, solo tiene que estar separada.

Solo piensa en ello. Actualmente encuentra que un día no es suficiente para estabilizar convenientemente la liberación, ¿verdad? Con la nueva estrategia de ramificación, puede bifurcar 2 días antes del lanzamiento en lugar de uno, no hay problema. Si encuentra que incluso dos días no es suficiente, intente bifurcar 3 días antes, etc. La cosa es que puede aislar la rama de lanzamiento tan pronto como lo desee, ya que esto ya no bloqueará la fusión de un nuevo código con la rama de integración. Tenga en cuenta que en este modelo no es necesario congelar la rama de integración: sus desarrolladores pueden usarla continuamente , los lunes, martes y viernes, lo que sea.

El precio que paga por esta felicidad es una complicación de las revisiones. Estos tendrían que ser fusiones en dos ramas en lugar de una (versión + integración). Esto es en lo que debe enfocarse cuando pruebe un nuevo modelo. Haga un seguimiento de todo lo relacionado: el esfuerzo adicional que dedica a la fusión a la segunda sucursal, los esfuerzos relacionados con el riesgo de que uno olvide olvidar la fusión a la segunda sucursal, todo lo relacionado.

Al final de la prueba, solo agregue lo que rastreó y sepa si la cantidad de este esfuerzo adicional es aceptable o no. Si es aceptable, ya está. De lo contrario, vuelva a su modelo actual, analice qué salió mal y comience a pensar en qué otra forma puede mejorar.


actualización2

<copia de comentarios>

Mi objetivo es hacer que las historias se prueben y se puedan entregar (detrás o delante de un muro de configuración) dentro de una iteración, esto solo se puede lograr si los probadores están probando el trabajo realizado en la iteración (y no estabilizando el código de la iteración anterior).

</ copia de comentarios>

Veo. Bueno, yo no tengo experiencia directa con esa manera, pero he visto en iteración tipo pruebas realizadas con éxito en un proyecto relacionado con la nuestra. Como nuestro proyecto seguía el camino opuesto, también tuve el lujo de comparar cara a cara estos enfoques opuestos .

Desde mi perspectiva, el enfoque de prueba fuera de iteración parecía superior en esa carrera. Sí, su proyecto salió bien y sus evaluadores detectaron errores más rápido que el nuestro, pero de alguna manera esto no ayudó. Nuestro proyecto también salió bien y, de alguna manera, pudimos permitirnos iteraciones más cortas que ellas, y tuvimos menos (mucho menos) lanzamientos resbaladizos que ellos, y hubo menos tensión entre los desarrolladores y los probadores a nuestro lado.

Por cierto, a pesar de una detección más rápida a su lado, logramos tener aproximadamente el mismo promedio de vida útil del error (el tiempo de vida es el tiempo entre la introducción y la corrección , no entre la introducción y la detección). Probablemente incluso tuvimos una ligera ventaja aquí, ya que con iteraciones más cortas y versiones menos resbaladas podríamos afirmar que, en promedio, nuestras soluciones llegan a los usuarios más rápido que las suyas.

En resumen, todavía creo que el aislamiento de la línea de código de lanzamiento tiene mejores posibilidades de mejorar la productividad de su equipo.


en un pensamiento adicional ...

  • el aislamiento de la línea de código de lanzamiento tiene mejores posibilidades : al volver a leerlo, creo que esto podría dar la impresión de que te desaliento de que pruebes las pruebas en iteración . Me gustaría dejar perfectamente claro que no.

En su caso, el enfoque de prueba en iteración parece seguro de probar (er ... prueba ) porque parece tener una comprensión clara de cómo lograrlo ( tubería de prueba suave ) y cuáles son los principales obstáculos. Y, después de todo, siempre tiene la opción de recurrir a un enfoque alternativo si le resulta demasiado difícil acertar.

Por cierto, con respecto a los obstáculos, los que vale la pena seguir en ese caso serán problemas como la falla para reproducir el error en el lado del desarrollador y tarde para encontrar / tarde para verificar la corrección en el lado de los probadores. Estos también podrían atascar su tubería , como sucede ahora con las revisiones.

mosquito
fuente
1
Gracias por tus ideas. En cuanto a la ramificación, hemos probado un no. de enfoques (y de hecho he usado un número @ organizaciones diferentes en mi carrera). Nos hemos decidido por un maestro limpio que representa el código en producción, una rama de integración (basada en el maestro) que todos los desarrolladores utilizan con frecuencia (idealmente varias veces al día). La rama de integración se construye y prueba continuamente, con frecuentes implementaciones automatizadas de preparación. He intentado sucia mainline con gran éxito antes. Nuestro enfoque actual parece más controlado. Utilizamos paredes de configuración para una funcionalidad incompleta y no deseada.
Ben
1
@maple_shaft bueno, la primera vez que vi errores en el rastreador contra el conjunto de pruebas fue en 2002 o 2003. Y parecía ser una práctica bastante establecida en el equipo al que me uní en ese momento. En cuanto a los errores de orientación diferenciaciones entre prod y puesta en escena, de hecho, éstos parecen novedoso para mí desde la primera vez que he visto (y estaba muy sorprendido) fue hace menos de 2 años
mosquito
1
@gnat, parece sentido común, por eso me pregunto por qué no he oído hablar de eso antes. Ahora que lo pienso, tiene sentido porque todos los grupos de control de calidad con los que trabajé parecían perfectamente felices de eliminar errores, pero se volvieron llorones cada dos años cada vez que se les presentaban errores.
maple_shaft
1
@maple_shaft lol de acuerdo en que esta manera parece ser inmerecidamente rara. ¿Sabía por cierto que uno puede lanzar errores no solo en los probadores sino también en los escritores de documentos / especificaciones? - La versión 12 de la Guía de desarrollo dice "negro" en la página 34, línea 5; debe ser "blanco". - Asignado a John Writer. - Solucionado en la compilación 67. - Arreglo verificado en la compilación 89 por Paul Tester.
mosquito
1
Mi última respuesta, ya que no quiero convertirme en una sesión de chat, pero en mi última organización escribí un error contra un escritor de especificaciones y toda la división retrocedió en un momento WTF. Me dijeron rápidamente que tenía un "problema de actitud" y que no era un "jugador de equipo" y que no debía volver a hacerlo.
maple_shaft
8

Sin conocer la naturaleza de las historias de los usuarios y la cantidad de ellas, debo decir que un ciclo de lanzamiento de 1 semana parece extremo. El escenario anterior que describió está intrincadamente planificado e involucra una serie de diferentes ramas, puntos de fusión, transferencias, entornos y conjuntos de pruebas, más o menos creando un sistema humano donde un solo error en medio de la complejidad del plan puede causar una liberación tardía o mala calidad. Esto puede tener un efecto dominó en las versiones posteriores.

En mi humilde opinión, el calendario es demasiado apretado.

Puede aumentar la cobertura del código escribiendo pruebas unitarias más efectivas y también pruebas de integración específicas del entorno.

Puede aumentar la calidad del código introduciendo programación de pares y / o revisión de código, aunque eso se consume en un tiempo aún más valioso.

Una mejor estimación de los puntos de la historia del usuario también puede ayudar al limitar implícitamente las historias de los usuarios que entran en un solo lanzamiento, lo que reduce el denominador en su relación de riesgo.

En general, parece que tiene buenas prácticas y un buen sistema para manejar su ciclo de lanzamiento extremo. Parece que estás en el camino correcto.

árbol de arce
fuente
¡Si! Una semana con un gran producto en un lenguaje compilado que necesita pruebas de integración con viento no es continuo, es extenuante . ¡Sigue así por demasiado tiempo y experimentarás la mortalidad laboral!
ZJR
+1; estamos ejecutando iteraciones de tres semanas en este momento y descubrimos que funciona bien.
Duncan Bayne
@ZJR, ¿puede ampliar lo que quiere decir con atenuar en este contexto?
Ben
@Duncan, nuestras iteraciones son de 2 semanas, pero estamos intentando incrementos de una semana . Esto puede o no ser posible / una mala idea. La idea es que un incremento de una semana contendrá menos código nuevo y, por lo tanto, contendrá menos problemas.
Ben
1
@Ben Aston, la cantidad de código no crea problemas, los plazos poco realistas, el estrés y las altas expectativas crean problemas.
maple_shaft
1

¿Por qué no utilizar la implementación continua real, donde una confirmación (o inserción) hace que las pruebas se ejecuten, y si las pruebas pasan, se produce una implementación?

Luego, si no está seguro de un cambio, lo hace en una rama separada, lo que aún hace que las pruebas se ejecuten pero no la implementación.

Creo que hay más estrés al tratar de lograr un tronco / maestro roto para la estabilidad que lo que hay, ya sabes, solo para mantenerlo estable.

Ricky Clarkson
fuente