evitando ramas largas en grandes historias

Estoy tratando de resolver el siguiente problema que tenemos en nuestra empresa: estamos tratando de seguir SCRUM. Estamos usando un modelo de ramificación similar a git-flow. Cuando encontramos una historia más grande que toma 2,3 sprints, no se fusiona hasta que se completan todas las subhistorias. Como resultado, tenemos una rama de larga duración que es difícil de fusionar al final. Comenzamos otras historias basadas en una rama maestra que no está completamente actualizada debido a la gran rama de historias destacadas. Propuse fusionar los primeros subpisos para volver a dominar siempre que sea posible, pero la gerencia dijo que es demasiado arriesgado ya que los cambios podrían interrumpir las implementaciones. ¿Cómo lidias con historias y ramas de larga duración?

Realice fusiones con frecuencia o aumente las estimaciones para tener en cuenta los gastos generales de mantenimiento de sucursales y fusiones retrasadas.
¡Las historias deben poder completarse en un solo sprint por definición!
Su administración debe aprender que los incrementos pequeños y frecuentes son más seguros que las implementaciones masivas. No discuta sobre la filosofía de scrum ni tenga problemas con ellos. Cuando algo grande se rompe en la producción que podría haberse mitigado con lanzamientos más pequeños, tome ese punto de dolor y explique respetuosamente (use .pptx o .xlsx si puede) cómo podría haberse evitado esto en el futuro. Enmárquelo como un análisis de causa raíz; nada de "te lo dije" ni nada por el estilo.

Respuestas (6)

La idea de Scrum es terminar el trabajo en sprints para que puedas hacer transparente tu progreso. Si tiene historias que abarcan 2 o 3 sprints, ocultará el progreso y hará que el marco Scrum sea menos transparente.

Sería una buena idea centrarse en desglosar las historias más grandes. Esto puede ser un desafío al principio, pero es una habilidad que los equipos de Scrum deben adquirir para tener éxito.

Si encuentra que aún necesita mantener ramas de características de larga duración, considere el siguiente enfoque:

  • Combine las ramas de características de nuevo en el maestro con la mayor frecuencia posible.
  • Si no es posible volver a fusionarse con el maestro, considere fusionarse del maestro a su rama. De esa manera, su sucursal nunca se alejará demasiado del maestro.
  • Si tiene más de una rama de características de larga duración, considere fusionarlas regularmente. De esa manera, se reduce el riesgo de conflictos de combinación de ramas de funciones.
  • Finalmente, considere usar integración continua para el proceso de fusión. Es posible configurar fusiones de rutina que brinden al equipo un aviso rápido de cualquier conflicto de fusión. Esto significa que el equipo resolverá los conflictos de combinación poco después de escribir el código que los causa.

'Cuando nos encontramos con una historia más grande que toma 2,3 sprints' .

No trabajes alrededor de eso, arréglalo. Debería poder fusionar una historia de INVEST . Observe que la S significa pequeño. Haga que sus historias secundarias sean valiosas y combinables. Tener historias monolíticas es un problema enorme (pero muy común). Sospecho que sus historias secundarias se asemejan a etapas en un diseño técnico, en lugar de incrementos de entrega. Eso no es del todo bien. La gente escribe libros sobre este tipo de cosas, pero lo vincularé a un diagrama de flujo muy simple y útil sobre cómo abordar la subdivisión de sus historias.

'Comenzamos otras historias basadas en un...' Tiene demasiado trabajo en progreso (WIP) y esta es una de las molestias menores. Mejore en la colaboración y acumule menos historias.

'pero la dirección dijo que es demasiado arriesgado' .

En primer lugar, esto podría estar relacionado con su problema WIP. Cuando terminas tu historia de varios sprints (épica podría ser una mejor palabra), siempre hay algún otro trabajo medio hecho en vuelo también. No quieren que todo esté en master, pero la solución no es sacarlo, es tener menos WIP.

En segundo lugar, las historias que recopile en cada iteración deben realizarse (Desarrollo, control de calidad en entornos de prueba, etc.) utilizando las habilidades dentro de su equipo. Necesitas lanzar cada iteración, ese es el punto. Es la forma en que entrega valor y obtiene comentarios de los clientes rápidamente. Necesitas retroceder contra esto. Pero también debe asegurarse de tener altos estándares de calidad (es decir, mucha automatización de pruebas) para que las personas no sientan que tomar su código es un gran riesgo.

TLDR La solución no es una administración de sucursales astuta y git no puede salvarlo. Divida sus historias y lea qué iteraciones se pretende lograr. O, supongo, presupuesto para fusiones horribles.

Usamos la técnica de cambio de función ([Alternar función de Wikipedia]: https://en.wikipedia.org/wiki/Feature_toggle ) y hasta ahora hemos sido muy efectivos para poder entregar a tiempo, manejar funciones grandes con gracia y desactivar funciones. que no se hacen antes de la fecha de lanzamiento.

Un conmutador de función (también interruptor de función, indicador de función, flipper de función, función condicional, etc.) es una técnica en el desarrollo de software que intenta proporcionar una alternativa al mantenimiento de múltiples ramas de código fuente (conocidas como ramas de función).

El lanzamiento continuo y la implementación continua brindan a los desarrolladores comentarios rápidos sobre su codificación. Esto requiere la integración de sus cambios de código lo antes posible. Las ramas de funciones introducen una derivación a este proceso. Los conmutadores de funciones devuelven a los desarrolladores a la pista, pero las rutas de ejecución de sus funciones aún están "muertas" si un conmutador está "desactivado". Pero el esfuerzo es bajo para habilitar las nuevas rutas de ejecución simplemente configurando un interruptor en "activado".

La técnica permite a los desarrolladores lanzar una versión de un producto que tiene características sin terminar. Estas funciones sin terminar están ocultas (alternadas) para que no aparezcan en la interfaz de usuario. Esto permite que se entreguen muchas versiones incrementales pequeñas de software sin el costo de ramificaciones y fusiones constantes.

Otro beneficio de las banderas de funciones son los lanzamientos canarios. Un lanzamiento de Canary (también conocido como implementación de Canary o lanzamiento de Canary) está implementando funciones para un pequeño número de usuarios para evaluar la reacción del sistema en general. Un lanzamiento canario le permite implementar una función lentamente y medir la reacción de los "canarios" de los usuarios reales, en busca de indicadores tempranos de peligro. Si una característica no es buena, se puede revertir. Los lanzamientos de Canary son una mejor práctica para las organizaciones de desarrollo ágil que practican la entrega continua para moverse más rápido.

Definimos la función que se puede enviar como un MVP de producto mínimo viable, que generalmente se traducirá como un Epic que se puede distribuir en muchos sprints o dentro de un Sprint (nuestro sprint dura una semana), un Epic se dividirá en varias historias de usuarios de INVEST, alta nivelado y centrado en el cliente. Todas las historias de usuario terminadas se fusionan en la rama principal a diario.

Otros han abordado el hecho de que sus historias son demasiado grandes, pero si las desglosa ( y debería hacerlo ), habrá hecho historias que pueden no estar listas para el "horario de máxima audiencia". No desea implementar estas funciones a medio hacer y tampoco su departamento de marketing.

Pero aquí está el secreto...

Quieres implementarlos . Es su departamento de marketing el que no quiere. Y ambos tienen razón .

El departamento de marketing no quiere que las funciones a medio hacer se conviertan en productos, pero desea fusionar estos cambios e implementarlos para que sea más fácil. Así que haces ambas cosas.

Escriba en un conmutador de funciones para estas funciones que llevan mucho tiempo en progreso. Combine sus historias cuando hayan terminado, como cualquier otra historia. Ahora, para fines de prueba/demostración, active la función, pero desactívela para la producción . Esto le permite fusionarse con frecuencia, enviar la función a su QA y propietario del producto para obtener comentarios rápidos, pero dejarla "sin enviar" para sus usuarios finales.

Cómo hacerlo podría llenar fácilmente una serie de publicaciones de blog, por lo que le dejaré más investigación sobre la alternancia de funciones.

Razonamiento divertido, su gestión. La fusión temprana de la rama corre el riesgo de interrumpir las implementaciones, por lo que es mejor agregar mucho más código a esa rama antes de fusionarla. ¿Exactamente cómo, por favor, diga, agregar muchas semanas de código disminuye el riesgo de romper la implementación?

Automatice su implementación e implemente con frecuencia en un entorno de prueba. Apunta a diario pero más frecuente si puedes. De esa manera, su 'implementación rota' siempre es causada por las pocas líneas de código que acaba de escribir. Fácil de arreglar.

Su gestión tiene sentido del humor.

Fusionar una rama obsoleta con la maestra es más fácil si crea una nueva estructura de directorios para la nueva función y luego realiza una fusión interactiva en lugar de una fusión automática:

Escribir afirmaciones en línea es de gran ayuda para grandes historias. Haga una revisión del código de las afirmaciones y genere un informe de prueba al final de cada sprint para mostrar el progreso. Esto evita la necesidad de:

  • Deslizamiento del alcance debido a una demostración de humo y espejos
  • Brechas de requisitos debido a la creación de API bajo presión
  • Problemas de seguridad debido a una revisión de código retrasada
  • Refactorización de última hora debido a suposiciones falsas

Referencias