svn - two - ¿La mejor estrategia de ramificación cuando se realiza una integración continua?
svn merge branch to trunk (11)
Creo que cualquiera de las dos estrategias se puede usar con desarrollo continuo siempre que recuerde uno de los principios clave que cada desarrollador se compromete con la troncalidad / línea principal todos los días.
http://martinfowler.com/articles/continuousIntegration.html#EveryoneCommitsToTheMainlineEveryDay
EDITAR
He estado leyendo un poco sobre este libro sobre IC y los autores sugieren que la ramificación por liberación es su estrategia de ramificación preferida. Tengo que estar de acuerdo. La ramificación por características no tiene sentido para mí cuando uso CI.
Trataré de explicar por qué estoy pensando de esta manera. Supongamos que tres desarrolladores toman una rama para trabajar en una función. Cada característica tardará varios días o semanas en finalizar. Para garantizar que el equipo se integre continuamente, deben comprometerse con la sucursal principal al menos una vez al día. Tan pronto como comienzan a hacer esto, pierden el beneficio de crear una rama de características. Sus cambios ya no están separados de todos los demás cambios del desarrollador. Siendo ese el caso, ¿por qué molestarse en crear ramas de características en primer lugar?
El uso de la bifurcación por publicación requiere una fusión mucho menor entre sucursales (lo que siempre es bueno), asegura que todos los cambios se integren lo antes posible y (si se hace correctamente) garantiza que la base de código esté siempre lista para ser lanzada. La desventaja de la bifurcación por lanzamiento es que tienes que ser mucho más cuidadoso con los cambios. Por ejemplo, la refactorización grande debe hacerse de forma incremental y si ya ha integrado una nueva función que no desea en la siguiente versión, debe ocultarse utilizando algún tipo de mecanismo de alternancia de funciones .
OTRO EDITAR
Hay más de una opinión sobre este tema. Aquí hay una publicación de blog que está pro ramificación de funciones con CI
http://jamesmckay.net/2011/07/why-does-martin-fowler-not-understand-feature-branches/
¿Cuál es la mejor estrategia de ramificación para usar cuando quieres hacer una integración continua?
- Release Branching: desarrolle en trunk, mantenga una rama para cada lanzamiento.
- Feature Branching: desarrolla cada característica en una rama separada, solo fusiona una vez estable.
¿Tiene sentido usar estas dos estrategias juntas? Al igual que en, ¿se ramifica para cada lanzamiento, pero también se ramifica para funciones grandes? ¿Una de estas estrategias se combina mejor con la integración continua? ¿Utilizaría la integración continua incluso tiene sentido cuando se utiliza un tronco inestable?
Creo que las herramientas que usas son un gran factor aquí.
- Si usa subversión, siga con la opción 1 y suelte de las sucursales.
- Si está usando GIT, la opción 2 funcionará bien para usted.
Cuando comenzamos nuestro equipo heredamos una estrategia basada en versiones del proveedor que originalmente desarrolló el sistema del que estábamos a punto de encargarnos. Funcionó hasta el momento en que nuestros clientes solicitaron que varias características desarrolladas no se incluyeran en una versión (fyi ~ 250k líneas de código, ~ 2500 archivos, Scrum con XP SDLC).
Luego comenzamos a buscar ramas basadas en características. Esto también funcionó durante un tiempo, como dos meses hasta que nos dimos cuenta de que nuestro proceso de prueba de regresión tardaría más de 2 semanas, lo que combinado con la incertidumbre de lo que se liberaría creaba un gran inconveniente.
El último "clavo en el ataúd" de las estrategias de SC puro vino cuando decidimos que deberíamos tener 1. tronco estable y 2. La producción debería contener BINARIOS de prueba ST, UAT y Regresión (no solo fuente - piense en CC).
Esto nos lleva a diseñar una estrategia que es un híbrido entre la característica y las estrategias SC basadas en la publicación.
Entonces tenemos un baúl. Cada sprint ramificamos en la rama Sprint (para los no ágiles, un sprint es solo un esfuerzo de desarrollo en el tiempo con salida variable en función de la complejidad). Desde la rama sprint creamos las ramas de características y comienza el desarrollo paralelo en ellas. Una vez que las funciones se completan y se prueban en el sistema, y recibimos la intención de implementarlas, se fusionan con la rama de sprint; algunas pueden flotar en varios sprints, generalmente los más complejos. Una vez que el sprint está cerca de su final y las características están completas ... "renombramos" la rama de sprint a "regresión" (esto permite que CruiseControl la recoja sin ninguna reconfiguración) y luego comienza la prueba de regresión / integración en el cc-built OREJA. Cuando todo está hecho, entra en producción.
En resumen, las ramas basadas en características se utilizan para desarrollar, la prueba del sistema y la funcionalidad UAT. La rama de sprint (realmente la rama de lanzamiento) se usa para combinar selectivamente las funciones según demanda e integración-prueba.
Ahora, esta es una pregunta para la comunidad: obviamente tenemos problemas para realizar una integración continua debido al hecho de que el desarrollo ocurre en muchas sucursales y la sobrecarga de reconfiguración de CruiseControl. ¿Puede alguien sugerir y aconsejar?
De la forma en que lo veo, quieres tener un conjunto limitado de ramas donde puedas concentrarte. Ya que desea pruebas, códigos de calidad y muchas cosas interesantes para ejecutar con las compilaciones, tener demasiados informes probablemente le hará perder información.
Cuándo y qué rama, generalmente depende del tamaño del equipo y del tamaño de las características que se desarrollan. No creo que haya una regla de oro. Asegúrese de utilizar una estrategia donde pueda obtener retroalimentación temprana / a menudo, y eso incluye tener calidad desde el comienzo de las funciones. El bit de calidad significa que a medida que se automatiza a medida que el equipo se desarrolla, si se ramifica para un gran conjunto de funciones que un equipo está construyendo, también debe tener calidad involucrada en el equipo.
ps ¿De dónde sacaste esas referencias de acercamiento? - No cree que esos gráficos representen todas las opciones
Actualización 1: Expandir por qué dije que no es una regla de oro. Básicamente para equipos relativamente pequeños, lo he encontrado mejor utilizando un enfoque que es una mezcla. Las ramas de características se crean si es algo largo y parte del equipo continuará agregando características más pequeñas.
Encuentro el tema realmente interesante ya que dependo mucho de las ramas en mi trabajo diario.
- Recuerdo a Mark Shuttleworth proponiendo un modelo para mantener la rama principal prístina mientras se va más allá de los CI convencionales. Lo publiqué here .
- Como estoy familiarizado con Cruise Control, también escribí sobre ramas de tareas y CI here . Es un tutorial paso a paso que explica cómo hacerlo con Plastic SCM .
- Finalmente, encontré algunos de los temas sobre CI (y potencialmente sobre ramificación) en el libro de Duvall sobre CI muy interesantes también .
Espero que encuentres los enlaces interesantes.
La integración continua no debe ser ningún tipo de factor para determinar su estrategia de ramificación. Su enfoque de ramificación debe seleccionarse en función de su equipo, el sistema en desarrollo y las herramientas disponibles para usted.
Una vez dicho esto ...
- no hay ninguna razón por la que CI no se pueda usar en los dos enfoques que describe
- esos enfoques funcionan bastante bien en combinación
- ninguno de los dos funciona "mejor" que el otro
- CI tiene sentido total con un tronco inestable
Todo esto fue respondido en la cuarta pregunta en la página que tomó los diagramas de: http://blogs.collab.net/subversion/2007/11/branching-strat/
La respuesta depende del tamaño de su equipo y de la calidad del control de origen y de la capacidad de fusionar conjuntos de cambios correctamente complejos. Por ejemplo, en el control de fuente de rama completa como la fusión CVS o SVN puede ser difícil y puede que estés mejor con el primer modelo, mientras que si utilizas un sistema más complejo como IBM ClearCase y con un equipo de mayor tamaño podrías ser mejor con el segundo modelo o una combinación de los dos.
Personalmente, separaría el modelo de rama de características, donde cada característica principal se desarrolla en una rama separada, con subdivisiones de tareas para cada cambio realizado por el desarrollador individual. A medida que las características se estabilizan, se fusionan con trunk, que se mantiene razonablemente estable y pasa todas las pruebas de regresión en todo momento. A medida que se acerca el final del ciclo de publicación y todas las ramas de características se fusionan, estabiliza y ramifica una rama del sistema de liberación en la que solo aplica correcciones de errores de estabilidad y backports necesarios, mientras que el tronco se usa para el próximo lanzamiento y usted nuevamente ramificarse para nuevas ramas de características. Y así.
De esta forma, trunk siempre contiene el código más reciente, pero logra mantenerlo razonablemente estable, creando etiquetas estables (etiquetas) en los principales cambios y fusiones de funciones, las ramas de características son desarrollo rápido con integración continua y las subdivisiones de tareas individuales pueden ser a menudo actualizado desde la rama de características para mantener sincronizados a todos los que trabajan en la misma función, al mismo tiempo que no afecta a otros equipos que trabajan en funciones diferentes.
Al mismo tiempo, tiene a través de la historia un conjunto de ramas de publicación, donde puede proporcionar backports, soporte y correcciones de errores para sus clientes que, por el motivo que sea, permanecen en versiones anteriores de su producto o incluso en la última versión lanzada. Al igual que con el enlace troncal, no configura la integración continua en las ramas de publicación, sino que se integran cuidadosamente al pasar todas las pruebas de regresión y otros controles de calidad de la versión.
Si por alguna razón dos características son co-dependientes y necesitan cambios entre sí, puede considerar desarrollar ambas en la misma rama de características o requerir las características para fusionar regularmente partes estables del código con el tronco y luego actualizar los cambios de tronco para intercambiar el código entre las ramas del tronco. O si necesita aislar esas dos características de otras, puede crear una rama común de la cual bifurque esas ramas de característica y que puede usar para intercambiar código entre las características.
El modelo anterior no tiene mucho sentido con equipos de menos de 50 desarrolladores y un sistema de control de origen sin ramas dispersas y una capacidad de fusión adecuada como CVS o SVN, lo que haría que todo este modelo sea una pesadilla para configurar, administrar e integrar.
Las ramas de publicación son muy útiles, e incluso absolutamente necesarias, si necesita mantener varias versiones de su aplicación.
Las ramas de características también son muy convenientes, sobre todo si un desarrollador necesita trabajar en un cambio enorme, mientras que otras todavía lanzan nuevas versiones.
Entonces para mí usar ambos mecanismos es una muy buena estrategia.
Interesante enlace del Libro de SVN .
Recientemente me ha gustado este modelo cuando uso git. Aunque su pregunta está etiquetada como "svn", es posible que aún pueda usarla.
La integración continua puede ocurrir en cierta medida en la rama de "desarrollo" (o como se llame) en este modelo, aunque tener ramas de características de larga ejecución para lanzamientos futuros no lo haría tan rígido como para considerar cada cambio que sucede codificar en alguna parte. La pregunta sigue siendo si realmente quieres eso. Martin Fowler sí.
Siempre que comprenda los principios, siempre puede reinventar las mejores prácticas. Si no comprende los principios, las mejores prácticas lo llevarán tan lejos antes de desmoronarse debido a algún requisito externo conflictivo.
Para obtener la mejor introducción al Modelo Mainline, lea esto: https://web.archive.org/web/20120304070315/http://oreilly.com/catalog/practicalperforce/chapter/ch07.pdf
Lee el enlace. Una vez que tenga los conceptos básicos, lea el siguiente artículo del venerable Henrik Kniberg. Le ayudará a relacionar el Modelo Mainline con la integración continua.
Personalmente, creo que es mucho más limpio tener un maletero estable y una función de ramificación. De esta forma, los probadores y demás pueden permanecer en una única "versión" y actualizar desde el enlace troncal para probar cualquier característica que tenga código completo.
Además, si varios desarrolladores están trabajando en funciones diferentes, todos pueden tener sus propias ramas separadas, luego fusionarse con el enlace troncal cuando terminan y enviar una característica para ser probada sin que el probador tenga que cambiar a varias sucursales para probar diferentes funciones.
Como una ventaja adicional, hay algún nivel de prueba de integración que viene automáticamente.