Estrategias de Branching y Gestión de Entregables con Git

Estimados, comparto con ustedes esta joyita. Me ha servido muchísimo para ordenar mi estrategia de branching, espero que sea un aporte para ustedes también.

Saludos,
Daniel

2 Me gusta

(Copiado desde twitter, por ende en formato breve de 140-caracteres cada una)

  • La mayoría de los proyectos OSS no usan el modelo de gitflow. La rama “develop” no tiene mucho sentido.

  • master + release branches (+ feature branches cuando el proyecto crece) es más simple, mismo resultado

Bueno al menos en mi caso uso develop como branch principal de desarrollo y master como reflejo de la perfección. De esta forma tengo un branch que siempre refleja la última versión que está en un nivel de calidad para producción. Los releases no siempre van a estar en este estado ya que luego de sacar un release viene un periodo de correcciones. Y develop idealmente nunca va a estar por mucho tiempo en un estado de perfección por razones obvias. Entonces el rol del branch master es ser el final de un proceso de desarrollo, representa lo mejor de una determinada versión. Ningún otro branch representa eso.
Ahora, los años me han enseñado que la mejor estrategia va a depender de la experiencia personal y de la capacidad de administrar el desarrollo de cada equipo. Y por esta razón te digo si tu estrategia produce los resultados que esperas genial !

1 me gusta

Y develop idealmente nunca va a estar por mucho tiempo en un estado de perfección por razones obvias

Esa es la parte que nunca he entendido de este modelo. Si un cambio X no está 100% decente (faltan tests, falta refactor, falta review, lo que sea), entonces puede ir su propia rama temporal (sea una feature-breanch o una que derechamente es wip) hasta que esté decente. Así no le mandas cosas a medias a los otros miembros de tu equipo, sólo a los que están trabajando en ese cambio.

Hecha esa distinción, develop es indistinguible de master :wink:

Y por esta razón te digo si tu estrategia produce los resultados que esperas genial !

+1.

1 me gusta

He estado aprendiendo gitflow luego de mucho tiempo de postergarlo, ya casi por un mes en varios proyectos, y generando algo de opinión sobre el tema. Antes utilizaba comits a master directo en proyectos pequeños (algunos siguen en ese modo) y en los mas complejos, feature-branches desde master. He encontrado el cambio bueno y hasta ahora no he sufrido grandes contratiempos y a la vez he ganado algunas cosas (a mi parecer)

develop es casi indistinguible de master, como dice @leosoto pero solo en proyectos que todo (o casi todo) push pasa a producción inmediatamente o muy pronto (deploy continuo) o que tienen altamente automatizado/simplificado el proceso de pasar a producción, cosa de que no necesitan mayor intervención humana entre source y live product.

Encuentro útil el modelo en el caso de tener entregables periódicos planificados, es decir, una vez a la semana o más, en donde un push no es necesariamente un deploy inmediato, por ejemplo en el caso de los famosos “release trains” o de los sprints de scrum, y se puede perder la sincronización entre prod y source si no se realizan tags de manera adecuada. También lo encuentro muy aplicable cuando no se tiene un proceso completamente automatizado o cuando se desea tener la capacidad de publicar a producción sólo hasta cierto punto en el tiempo y no el siempre el “lastest” y aun mantener un log en git ordenado y claro como el agua.

Particularmente útil, encuentro el tener ramas de publicación entre develop y master, para realizar todas las preparaciones intermedias como versionamiento, generación de artefactos (docs, scripts de migración, etc) que se preparan en esta rama y luego se pasan a master. Esto permite trabajar tranquilo en el deploy mientras otras cosass suceden en develop. Especialmente recomendado para quienes no tenemos aun todo el proceso de release automatizado :wink: y queremos mantener el log de git ordenado.

Mi experiencia hasta ahora es que efectivamente hay un mayor relajo con la calidad de lo publicado a develop, versus el push directo a master… lo que nos ha causado algunos problemas, nada serio hasta ahora, pero tampoco somos muchos ni trabajamos en proyectos muy complicados. Si nos ha disparado los commits, al parecer porque se reduce el miedo de contaminar master con pequeñeces. Yo cuidaría mucho el aspecto de la calidad y sería más estricto con lo que cae a develop manteniendo el criterio de tener ahí código siempre publicable. Es decir, mezclar a develop debiera implicar dar el feature por hecho.

Aparte de eso, las herramientas tanto de línea de comando como las gráficas ayudan mucho con el flujo y lo hacen más agradable… pero puede ser aun el honeymoon phase. les cuento de vuelta con más experiencias en unos meses =P.

1 me gusta

La lógica es que luego de hacer releases se pueden encontrar problemas, al menos a mi me ocurre con una certeza cercana al 100% y por lo tanto es necesario corregir y sacar un nuevo release. Pero no se toca master hasta llegar a un nivel de estabilidad con los releases.
En cierta forma el proceso contempla el hecho que el primer release de una versión aún no se ha sometido al rigor de producción y por lo tanto falta validar que ese aspecto esté ok. El modelo refleja esto. Si estas usando este modelo entonces luego de sacar el primer release de una versión tu asumes que ese release no está perfecto con un alto grado de probabilidad, y cuando lo pasas a master estas diciendo que ahora si tiene un nivel de calidad aceptable. Entonces la meta del modelo es llevar los releases a master en un timeframe apropiado para cada proyecto. Y si un release ha pasado a master es porque ese release cumple con el estándar de calidad que se ha fijado para el proyecto. Ninguna otro branch refleja esto.

Saludos

1 me gusta

Si definitivamente, este es un modelo que requiere que los push no pasen directo a producción.

En lo personal creo que es bueno tener un cierto nivel de ceremonia y un modelo explícito con el objetivo de que todos los integrantes puedan mapear sus analogías internas a un modelo concreto (sea cual sea).
Hasta ahora no he conocido un proyecto en donde los push pasen directo a producción con deployment y testing 100% automatizado. Considerando que alguien tiene que hacer los tests de integración o bien validar cobertura o cualquiera de las actividades habituales de aseguramiento de calidad.
Puedo imaginar que un equipo altamente experimentado puede lograr algo cercano a eso, en un proyecto de bajo riesgo/impacto. Pero en la mayoría de los proyectos que he participado el riesgo de subir un error a producción es simplemente demasiado caro versus la necesidad de tener el cambio pronto.

Saludos y gracias por la elaborada respuesta. Será interesante conocer la conclusión de tu experiencia.

Saludos

1 me gusta

En lo personal llevo mucho tiempo trabajando en una estrategia de branching basada en features, siendo esta misma rama la que paso para revision o para deploying en ambiente de pruebas por los demás personas. Y luego a traves de pull request con revisiones por parte de todos los miembros del equipo cuando se hace necesaria la integración a master.
PERO en los dos últimos proyectos he adoptado integramente gitflow y la verdad en principio me parecía un monton de pasos innecesarios pero a medida que los proyectos han ido creciendo he entendido y he aprendido (creo) el sentido de todas esas ramas aparentemente innecesarias.
Acá mi experiencia:

master: Rama productiva que contiene el último release y el tag (la version) con sus parches (hotfixes).
develop: Contiene la ultima version estable de features, rama para probar y a veces para recibir feedback de clientes. Esta rama suelo tenerla en un ambiente de staging con datos (si es web) lo mas cercanos a producción.
features: Branches que salen de develop que son inestables para probar nuevas carácteristicas y funcionalidades. Muchas de estas a veces son pruebas de concepto, las compartimos y modificamos pero en ambientes absolutamente de desarrollo y test.
releases: Salen de develop (version estable de feature(s)) y solemos pasarlas a QA (cuando hay QA) o le hacemos QA entre nosotros tratamos de ponerlas en ambiente semi productivo en “rodaje”, staging o a veces la ponemos en producción en ciertos momentos de poco tráfico. De las ramas release sale el tag que pasa a master; no antes. Jamas pasamos algo a master antes de estar en un release. Basicamente porque dada la urgencia de algunas caracteristicas puede que develop ya haya avanzado hacia otro nivel. Asi cuando cerramos un release se actualiza develop y master. Volviendo el ciclo.
hotfixes: Estas ramas salen directamente de producción y se integran directamente a master actualizando también develop. Esto tiene mucho sentido dado que son justamente eso hotfixes por lo tanto no vale la pena iniciar una iteración completa del ciclo por un parche. Eso si hay que tener cuidado de que tu master no se llene de parches. Pero eso se previene pasando primero por develop, release.

A alguno quizás les parece mucho, pero creanme cuando tienes que hacer releases todo el tiempo y nuevas características o pruebas de conceptos están entrando super rápido, al menos para mi me funciona mucho mejor tener separadas las aguas. Tener un proceso de integración a master mucho mas limpio que solo hacer el pull request tradicional, muchos menos problemas se nos pasan a master ahora usando gitflow.
Pero solo es mi experiencia, a algunas personas se les complica mucho manejar muchos ambientes sobre todo si no usan buenas herramientas de deploying.
Eso.

3 Me gusta

Me parece muy bueno el uso que le das a develop, yo hago algo similar pero es un poco menos elegante.
Realmente interesante lo que comentas.
Cual es el tamaño promedio de tu equipo ?
Cuál es el nivel de experiencia de los integrantes ?

Saludos,
Daniel

1 me gusta

En mi trabajo somos 5 developers todos seniors. Y en mi empresa personal y emprendimiento depende el proyecto pero interactuamos entre 4 a 10 personas, entre practicantes, desarrolladores ui/ux y nosotros.

Donde trabajo hemos tenido diversas experiencias con gitflow, buenas y malas. En lo personal, me gusta mucho para equipos grandes. Tal como dice @leosoto la rama de develop no tiene mucho sentido sobre todo si estás con CI.
Ahora, me gustaría consultarles por alguna recomendación o modelo para productos.
Mi situación es la siguiente: un producto “base” y distintos forks x cliente. Me es difícil hacer pull request al repo padre sin llevarme cambios indeseados. Me ayudaría un modelo de branching en lugar de forks??

@jchacana estoy en lo mismo, experimentando mas que nada. De momento lo que estoy haciendo es modularizar todo y cada “modulo” (gem en ruby) lo trato como un miniproyecto así dependiendo del proyecto agrego o no ciertos modulos y el proyecto como tal parte como una entidad aparte (limpiecita, si se quiere). Pero seria bueno tener mas feedback para hacer lo que dices buscar la mejor forma, quizas creas un hilo aparte?
saludos

develop sí es distinto de master en el modelo de gitflow

develop tiene features en desarrollo, por ejemplo cuando se requieren varias historias para completar una característica completa. Se pueden desactivar lo nuevos features usando feature toggles en lo así llamado release trains. Todo el código en develop compila, tiene tests y cumple con clean code.

master es el que guarda las versiones oficiales en producción, se usa para hacer seguimiento de las distintas releases que han pasado a producción. Tiene un tag por cada paso a producción y así es más fácil saber cuándo una rama release se pasó a producción en master.

La gracia con git es que hacer ramas es barato y el merge es más sencillo que con otros herramientas de versionamiento como SVN. Lo que no quita que a veces el merge sea difícil o complejo.

En lo personal, me gusta mucho gitflow. En mi empresa actual no lo usamos. En la anterior sí lo usábamos.

Me pasó una vez que una persona influyente de mi equipo no le gustaba el modelo de gitflow y dijo “no es necesario tanta burocracia y enredo con gitflow, vamos a usar la pura rama master y vamos a seguir el modelo de Branch By Abstraction” Branch By Abstraction de branch no tiene nada, es sólo un título para decir, empieza tu código envolviendo la característica actual en una clase wrapper, extiéndela por debajo y termina reemplazando lo viejo por lo nuevo. Lo otro que le pusieron de condición a la rama master fue de siempre hacer los commits por encima usando rebase y no usar merge commits, “para que no se vea sucia la historia y sea más fácil armar la lista de historias en el reporte de paso a producción”

Muy interesante tu experiencia.
En el equipo que no son todos seniors, les costó mucho subirse a la micro del gitflow ?

Saludos,
Daniel

Hoy me topé con un post sobre git del equipo de desarrollo de ArchDaily y me acordé de este hilo.

Para mí lo más simple que podría funcionar es equipo haciendo commits en master y manteniendo disciplina via TDD (y opcionalmente CI)

Lo siguiente (cuando lo anterior no funciona) sería el flujo que tienen ellos, que permite desarrollar cosas paralelas sin tanta complicación: http://archdaily.github.io/softwre-engineering/git/gitflow/2014/03/19/our-gitflow.html

Y cuando la escala del equipo/producto haga que eso no funcione, algo tipo gitflow entraría en mi radar :wink:

1 me gusta

Bueno yo lo he hecho.

El secreto es tener una máquina de integración + una máquina de testing (para el testing manual) + una máquina de staging (testing manual en una ambiente “idéntico” a producción + máquina de producción.

La integración corre los test unitarios (JUnit) y funcionales (Selenium) automatizados.

La máquina de testing es para que los desarolladores hagan testing si lo necesitan. Se contruye en la noche y la hora de almuerzo con el mismo branch de desarrollo.

La máquina de Staging usa el branch de staging y la máquina de producción el branch de producción. Ambas se compilan y se instalan todas las noches.

La idea es que los scripts de base de datos están bajo Git. Un script de creación de BD y luego escripts de carga de datos iniciales y los datos de “prueba” necesarios. Se corre los test unitarios y funconales en la máquina de testing. Luego drop database y se vuevle a instalar el script de creación + datos iniciales y queda listo para las pruebas manuales.

En staging no se puede hacer un drop database y crear la BD de nuevo, se debe hacer un upgrade database. Eso se hace guardando en una tabla db_version la versión actual. Dentro de ant, maven o gradle hay un proceso que lee archivos de un directorio “db:upgrade” del proyecto y ahí se encuentran los upgrades numerados. Si la BD está en la versión 308 y dentro del directorio se encuentre 309.sql, 310.sql, 311.sql, entonces esos archivos se deben ejecutar en ese orden.

Todas las noches corre staging. Entonces cada vez que se termina un feature tomo “develop” y le hago merge con “staging”. Si en la noche pasa todo bien, y la funcionalidad pasa todos los tests funcionales, pasar a producción es tan simple como hacer merge de “staging” a “production”.

Nota: Nunca tuve que hacer cambios “urgentes”, lo más urgente siempre tomaba 2 días. Un día para pasar a staging y otro día para pasar a producción.

Esto es por diseño, si todo está probado, entonces nunca hay “condoros” graves que arreglar.

Ahora bien, suponiendo que no tengo tiempo para hacer todo el proceso y el cambio debe estar inmediatamente, lo único que debo hacer es hacer directamente el cambio en “production”, ni compilar en mi máquina y meterme a Jenkins y recompilar la máquina “production”. Chan-chan. Van a estar 15 minutos sin sistema, pero se supone que el problema era realmente grave, no?

Si quieren nunca tener el sistema abajo tendríamos que usar Cassandra.

“Considerando que alguien tiene que hacer los tests de integración o bien validar cobertura o cualquiera de las actividades habituales de aseguramiento de calidad.”

Todo eso se puede automatizar y no sólo funciona, sino que no pierdes tiempo y dinero haciéndolo.

Lo que nunca he automatizado es que la funcionalidad tenga sentido desde el punto de vista de negocio, es decir, no saco nada con tener una página para agregar un nuevo cliente si lugo no lo puedo consultar. De la msima manera no saco nada con consultar clientes si luego no puedo agregarlos.

1 me gusta

¿es idea mía o esto es gitflow sin usar gitflow + usemos “increment version.sh” ?

1 me gusta

Después de saber que Facebook tiene esencialmente el mismo modelo que la mayoría de los proyectos OSS, (es decir, master + algunas ramas long-lived para releases + pocas ramas short-lived para experimentos/topic-branches) ya estoy más convencido que la rama “develop” de gitflow no tiene sentido.

1 me gusta