Evite que las ramas se acumulen

19

Estamos comenzando a encontrarnos con un problema a medida que crecemos, donde las características llegan a la fase de prueba, pero para cuando todo se prueba y las nuevas características aprobadas están en fase de prueba.

Esto está creando un entorno en el que casi nunca podemos impulsar la producción porque tenemos una combinación de características probadas y no probadas. Estoy seguro de que este es un problema común, pero aún no he encontrado buenos recursos para nosotros.

Algunos detalles:

  • GIT en BitBucket
  • Jenkins para la implementación con script en Azure

Lo que espero es una forma de aislar las características a medida que se mueven a través de entornos y solo empujan lo que está listo para pinchar.

Wesley
fuente
1
¿Está ramificando para cada característica, o está enviando cambios de características directamente a la rama del servidor de prueba?
Robert Harvey
1
Sin información sobre cómo administra las funciones y las sucursales, no podemos dar una respuesta específica a sus problemas.
Michael Durrant
2
¿Trabaja con iteraciones de alguna manera (por ejemplo, sprints de dos semanas o lanzamientos versionados)?
RemcoGerlich
@RobertHarvey: Estamos bifurcando para cada característica, pero tenemos una rama de Desarrollo, Etapa y Producto en la que combinamos que construye e implementa automáticamente esa rama en combinación.
Wesley
@RemcoGerlich: Trabajamos en sprints de tres semanas en este momento, pero con ocho desarrolladores no hay garantía de que el progreso que hacemos en cada ciclo sea perfecto en todos los ámbitos.
Wesley

Respuestas:

22

Parece que tienes algunos problemas aquí:

1. Identificación de funciones para una versión específica

Este es un problema de gestión de proyectos y un problema de coordinación. ¿ Esta función se lanzará antes, al mismo tiempo o después de esta otra función? Si las versiones quieren que ocurra una característica a la vez, identifíquelo. Si las características se van a agrupar en versiones, averigüe cuáles son las agrupaciones y aplíquelas con los desarrolladores y los responsables de la toma de decisiones. Use su sistema de seguimiento de problemas o tickets para etiquetar los lanzamientos. Deje en claro que si una característica de un lanzamiento específico es un no-go, entonces todos lo son.

2. Estrategias de ramificación

Git-flow es la respuesta fácil para problemas como estos, y a menudo las personas usan una variante de git-flow incluso si no saben de qué se trata. No voy a decir que es un problema para todos los problemas, pero ayuda mucho.

Parece que se encuentra con un problema con las estrategias de lanzamiento no deterministas, donde las características son scattershot aprobadas y algo que comenzó a desarrollarse hace mucho tiempo podría lanzarse después de algo que comenzó más recientemente: características de salto de rana.

Las ramas de características de larga duración o las versiones de lanzamiento simultáneas son probablemente la mejor respuesta para este tipo de problemas. Fusiona (o modifica, si te sientes cómodo) lo último de master en tus ramas de larga duración. Tenga cuidado de fusionar solo las características que ya están activas, de lo contrario, se encontrará con los problemas que ha tenido ahora (demasiadas características mezcladas en una rama).

Las ramas "revisión" o "corrección de errores" son una parte esencial de este proceso; úselas para pequeñas soluciones únicas que tienen un ciclo corto de control de calidad.

Según su descripción, incluso podría ser mejor no mantener una rama oficial de "desarrollo". En cambio, bifurque todas las características fuera del maestro y cree bifurcaciones de lanzamiento fusionadas una vez que se identifica un lanzamiento.

3. Ambientes

No combine las ramas de git con sus entornos, excepto para la producción == master. Se debe suponer que la rama de "desarrollo" está rota. Las ramas de lanzamiento se envían a entornos de prueba, ya sea un entorno de control de calidad o un entorno intermedio. Si es necesario, inserte una rama de características específicas en un entorno.

Si tiene más de una rama de características que necesita ser liberada por separado pero que se están probando al mismo tiempo ..... ¯ \ _ (ツ) _ / ¯ .... ¿activar otro servidor? Quizás fusionarlos en una rama desechable ... comprometer arreglos / cambios en las ramas originales y volver a fusionarse en la rama desechable; hacer la aprobación final y UAT en las ramas de lanzamiento individuales.

4. Eliminar características no aprobadas de una sucursal

Esto es lo que los pensamientos anteriores intentan evitar, porque sin duda es lo más doloroso de tratar de hacer. Si tiene suerte, las características se han fusionado en su desarrollo o ramas de prueba atómicamente usando merge commits. Si no tienes suerte, los desarrolladores se han comprometido directamente con la rama de desarrollo / prueba.

De cualquier manera, si usted se está preparando para un lanzamiento y tienen cambios no aprobados, necesitará usar Git a echarse atrás esas confirmaciones no aprobados por la rama de lanzamiento; La mejor idea es hacerlo antes de probar el lanzamiento.

La mejor de las suertes.

Jen
fuente
NB: por "ciclo de control de calidad corto" para las sucursales de hotfix, estoy hablando de algo que será impulsado a la producción dentro del día, más o menos. Emergencias Algunas personas no los usan de esa manera, pero eso es lo que yo y mi equipo hacemos y parece funcionar bien para nosotros.
Jen
anuncio 1: la pregunta tiene una etiqueta de "integración continua", por lo que creo que el OP quiere lanzar funciones inmediatamente a producción una vez que se prueban (suficiente). Por lo tanto, el resultado de la prueba podría controlar el orden de lanzamiento a producción, lo cual es un poco contrito a su recomendación.
Doc Brown
... sin embargo, creo que esta es una muy buena respuesta.
Doc Brown
De acuerdo: eliminé el bit de "orden" de la primera sección. Creo que "ordenar" es menos importante que identificar lanzamientos. Si CI es el objetivo, entonces mantener características distintas para pruebas y lanzamientos es definitivamente más importante que mantener un cronograma.
Jen
Por lo general, tampoco recomendaría eso, pero la pregunta se hizo específicamente sobre tratar de administrar el código donde ciertas características no se probaron ni se aprobaron. Raramente trabajo en proyectos que tienen tanta incertidumbre acerca de qué características se lanzarán cuando, por lo general, el calendario de lanzamiento está bastante planeado, y un retraso en un lanzamiento retrasaría el siguiente también. ¿Qué harías en su lugar?
Jen
4

Aquí hay una idea, deje de usar ramas de lanzamiento. En su lugar, comience a incorporar las funciones y actívelas mediante la configuración. De esa manera, siempre está fusionando ramas de características en maestras y nunca debería haber una pregunta sobre qué versión está en prueba o producción. Si tiene alguna pregunta sobre qué funciones / implementaciones están activas en un entorno, simplemente verifique el archivo de configuración.

RubberDuck
fuente
3

Esto debería ser una simple cuestión de coordinación entre prueba y producción. Si está utilizando ramas de características en Git, simplemente deje de presionar las ramas de características completadas para probar durante un ciclo de prueba, y reanude cuando se complete la prueba.

Si necesita un mejor control que esto, separe la Prueba en un servidor de Desarrollo y un servidor de Prueba de aceptación, y coordine esas ramas que serán enviadas al servidor de Prueba de aceptación con el equipo de prueba. Entonces, alguien puede ser responsable de iniciar el despliegue final desde la Prueba de aceptación hasta la Producción.

Robert Harvey
fuente
2

El trabajo se acumula

Este es un problema universal en mi experiencia. Lo abordo con:

  • Gestión sólida de lanzamientos de funciones por parte del propietario del producto.
  • Asegúrese de que las ramas se eliminen cuando se fusionen
  • Limite el trabajo en progreso (con límites de columna en Jira)
  • Revisión trimestral de tickets antiguos que languidecen, tanto errores como características
  • Retrospectivas para discutir los componentes del problema.
  • Aliento constante para que todos revisen el código
  • Oportunidades de emparejamiento para abordar boletos y problemas de larga data
  • Reuniones trimestrales para revisar y limpiar boletos viejos
  • Enfoque en equipo para que el desarrollador, el producto y el control de calidad trabajen juntos
  • Buenos informes y herramientas para hacer obvias las nuevas características del producto y la cartera de pedidos
  • Revise las sesiones para revisar las ramas antiguas y eliminarlas
Michael Durrant
fuente
2

Ramas

Necesita algunas ramas para controlar ese proceso:

  • característica : estas ramas nacen del maestro. Use alguna aplicación de gestión de proyectos para identificar cada rama de características con alguna tarea. Por ejemplo, si se utiliza TRAC, el resultado final será si ramas como: 1234-user-crud, 1235-bug-delete-catalog, etc. Identificar sus confirmaciones con el número de tarea también, esto le ayudará mucho cuando se tienen problemas en fusiones (se quiere).
  • prueba : todas las ramas de características que se realizan se fusionarán con la rama de prueba. Usted nunca se fusiona la rama de prueba en alguna rama de la funcionalidad , ya que no desea que el código de otra de las características que no están en la producción (maestro). Lo mismo es válido para la releasesucursal.
  • lanzamiento : cuando decide qué características probadas pueden estar en la producción, fusiona estas ramas (de nuevo ...) en esta rama. Debe probar todas las funciones nuevamente, porque esta fusión puede traer nuevos problemas. Cuando la versión se prueba y se hace, se fusiona esta rama en maestra y se crea una etiqueta en maestra para la versión.
  • maestro : contiene solo el código de producción.

Ver el flujo de git:

                              |FEAT_2|
                                  |
                             .---C06<-------.---------.
                            /                \         \
                           /   |FEAT_1|        \         \
                          /       |            \         \
                         /    .--C07<--.--------\---------\---------.
                        /    /          \        \  |TEST| \         \
                       /    /            \        \    |    \         \
                      /    /        .-----`--C09<--`--C10    \         \ |RELEASE|
                     /    /        /                          \         \    |
    <v4.6.0>        /    /        /                       .----`--C11<---`--C12<--.
       |           /    /        /                       /                         \
C01<--C02<--C04<--´----´--------´-----------------------´---------------------------`--C13
 |           |                                                                          |
<v4.5.0>  <v4.6.1>                                                                   |MASTER|
                                                                                        |
                                                                                     <v4.7.0>

Ambientes

Muy simple:

  • prueba : este entorno utiliza la rama de prueba.
  • lanzamiento : este entorno utiliza la rama de lanzamiento real.

Los desarrolladores trabajan en su máquina, cada uno con su propia base de datos. Si no es posible, cada desarrollador tiene una base de datos individual (debido a las licencias, el tamaño de la base de datos, etc.), tendrá muchos problemas para compartir una base de datos entre los desarrolladores: cuando alguien elimina una columna o una tabla en su rama, los demás sucursales todavía cuenta con esta columna / tabla en la base de datos.

Problemas

El mayor problema en este proceso son las fusiones.

Necesita rehacer las mismas fusiones en testy release. Esto será doloroso si se realiza un buen refactor en el código, como eliminar una clase, mover / cambiar el nombre de los métodos, etc. Como no puede obtener el código de test(o release) bifurcación en la bifurcación de características, las confirmaciones de fusión solo se pueden resolver en el test(o release) Entonces, terminas resolviendo los mismos conflictos en dos ramas diferentes, probablemente produciendo un código diferente en cada fusión y, en el futuro, descubrirás que el equipo de prueba necesitará probar las características dos veces: en las ramas testy release, porque cada fusión puede dar lugar a diferentes errores.

Otro problema es la testrama. Tendrá que "reciclar" esta rama (eliminar y crear una nueva master) de vez en cuando, porque algunas ramas antiguas (o fusiones antiguas, ramas fusionadas que se eliminaron) pueden traer muchos problemas para el nuevo código, divergiendo mucho de lo que hay adentro master. En este momento, necesita el control de qué ramas desea fusionar nuevamente en test.

La mejor solución es que el equipo de negocios sepa lo que debe entregarse en la próxima versión y todos trabajen en una rama única (rama de desarrollo). Es bueno para ellos la posibilidad de elegir la función "hecho" que les gustaría tener en la próxima versión en cualquier momento que quieran (creo que este es su escenario), pero esto es una pesadilla para los desarrolladores y (creo) para el equipo de prueba

Dherik
fuente
@DownVoter, ¿por qué?
Dherik
0

Parece que está fusionando los cambios de su rama de integración en su rama de producción, lo que en mi humilde opinión no es una buena práctica, exactamente por las razones que menciona. Tan pronto como una rama de producción para una determinada versión se extrae de la rama de integración principal, la rama de integración puede, en cualquier momento, divergir (después de todo, se supone que evoluciona hacia la próxima versión). La fusión de la rama de integración en la rama de la versión actual puede traer cambios incompatibles con esa versión.

En mi humilde opinión, un proceso adecuado sería:

  • extraiga una rama de producción de la rama de integración solo cuando se considere que está lo suficientemente cerca del nivel de calidad deseado, de modo que solo se espera un puñado de cambios para completar el lanzamiento. En otras palabras, la finalización de características debe evaluarse (continuamente) en la rama de integración, antes de extraer la rama de producción.
  • después de que se retira la rama de producción, solo se introducen los cambios seleccionados, tratados como cambios independientes / arreglos puntuales, es decir, se verifica que realmente funcionan como se esperaba (solo porque un cambio funciona en una rama no necesariamente significa que también funcione en otra rama)
Dan Cornilescu
fuente
0

Personalmente, esto parece que podría ser un problema de proceso más que un problema de herramientas. Algunas cosas que sugeriría aquí:

  • No estoy seguro si tiene grupos de desarrollo y control de calidad separados. Si lo hace, asegúrese de que tanto Dev como QA participen en reuniones de planificación y estimación de sprint. En una de mis compañías anteriores, nos aseguramos de que el número de puntos de historia que asignamos a una historia representara tanto el esfuerzo de desarrollo como de prueba. (Teóricamente, también podría tener dos estimaciones separadas para el esfuerzo de desarrollo y control de calidad, pero de cualquier manera necesita que su estimación incluya ambas; el tiempo requerido para una historia es el tiempo necesario para entregarla). Incluso si no tiene un grupo de control de calidad separado, asegúrese de incluir el esfuerzo de prueba en sus estimaciones.
  • En una línea similar a la anterior, acuerde de antemano cuántas historias va a incluir en un sprint en particular. La cantidad de puntos de historia que aceptas se basa en la cantidad que tus desarrolladores pueden terminar en su sprint y la cantidad de elementos que QA puede probar en su sprint. (Supongo, por supuesto, que los sprints de QA están detrás de los sprints de Dev, pero puedes adaptar esto a tu proceso). Si sus desarrolladores pueden terminar 200 puntos de historia pero su control de calidad solo puede terminar 150 puntos de historia, obviamente solo puede hacer 150 puntos de historia antes de que el trabajo comience a "acumularse" y termine con un caso como el que describe. (En un caso como este, es posible que desee investigar la causa del obstáculo para intentar mitigarlo).
  • Nadie transfiere nada al control de calidad hasta que todo lo que se encuentra actualmente en el control de calidad se pruebe y entregue .
  • Una característica completa es aquella que ha sido probada y entregada. Si no se entrega, no se hace.
  • Obviamente, desea intentar hacer esto en algún tipo de horario fijo. Una de las ideas completas detrás de la integración continua y ágil es la iteración. Por definición, la iteración implica entrega frecuente. Las integraciones y entregas frecuentes minimizan el riesgo de cada una.

Honestamente, creo que lo más importante será la disciplina sobre cuándo está entregando y cuántas tareas puede completar por completo en un período de tiempo determinado.

Para resumir: solo entregue a QA cuando haya terminado de probar y entregar las características anteriores.

EJoshuaS - Restablece a Monica
fuente
-2

Cuando "todo esté probado y aprobado", implemente lo que fue probado y aprobado para producción. Eso podría ser una confirmación particular, o podría ser un artefacto de construcción particular generado por Jenkins.

No debería importar que las confirmaciones posteriores en la misma rama aún no se hayan probado.

bdsl
fuente
1
Ciertamente es importante que las confirmaciones posteriores en la misma rama no hayan sido probadas y aprobadas: la implementación de código en producción que no se ha probado es una forma segura de conseguir un cliente enojado.
Jen
No estoy sugiriendo que las confirmaciones posteriores se implementen. Estoy diciendo que deje en paz esas confirmaciones posteriores, implemente la que se probó.
bdsl
En otras palabras, ignore las ramas, tome la decisión de implementación con respecto a los compromisos individuales o las compilaciones individuales.
bdsl