¿Por qué Trunk-Based Development?
Tags: git, develop, trunkbaseddevelopment, gitflow
Published: 2020-10-13 21:34:17

La eficiencia de un equipo se puede ver afectada por muchos factores uno de ellos, es la estrategia de Git. Si, aunque suene extraño, y el simple hecho de la manera en que integramos el código puede llegar impactar a productividad del equipo. Este blog post explica dos estrategias, GitFlow, la estrategia (más común) y Trunk-Based Development (poco conocida pero utilizada por equipos altamente eficientes). 

Empeceeemooos 🏁

### 🤔 ¿Qué es un estrategia en git?

Es la manera en la que se administran los branches y releases, en otras palabras como se integra y se hace que el código de desarrollo llegue al branch de producción.

### ¿Cómo funciona GitFlow?

![Screenshot 2020-10-12 at 4.14.38 PM](https://dev-to-uploads.s3.amazonaws.com/i/bprcbxha44n261oxa1la.png) 

No voy a profundizar mucho, pero les voy a contar que la primera vez que vi esta imagen me costó entenderla, seguir el flujo, lineas, y flechas de como el código se mueve de un lugar a otro, se me hizo confuso, pero después de mucho tiempo de utilizarla, les puedo comentar algunos pros y cons que nos da:

👍 Pros:

1. Alienta el uso de pull request.
2. Control estricto de los cambios, porque normalmente solo algunos desarrolladores esta autorizados para aprobar los pull request.
3. Después de entender como funciona, es simple de utilizar.

👎 Contras:

1. Los primeros 2 beneficios también se convierten en contras, porque el tener tanto control del proceso alienta y crea dependencia de una persona o varias personas encargadas al momento revisar los cambios, en algunos casos puede llegar a convertirse en micro-management.
2. El crear branches de larga vida (long-living branches),  puede provocar que cuando necesitemos unificar (mergear) el código se creen muchos conflictos sobre todo en equipos que están desarrollando una misma sección. Ej. Supongamos que se va a crear el branch de release para que se le empiecen a realizar pruebas, por otra parte, el equipo debe seguir desarrollando funcionalidades que no son parte del release y se continua integrando código al branch de develop, creando así 2 lineas de "tiempo" (develop y release). 
![Screenshot 2020-10-12 at 4.05.50 PM](https://dev-to-uploads.s3.amazonaws.com/i/a12ftivinz33ixx0fg41.png)
<small>*Release se convirtio en un branch de larga vida porque se le esta dando mantenimiento (agregando commits al branch)*</small>
Ahora, el equipo de QA encuentra un error en el branch de release, alguien salta y lo repara inmediatamente, pero no toma encuenta  que otra persona refactorizo la misma sección en el branch de develop, así que al momento que movamos los cambios de release a develop lo que va a pasar es  que nos encontramos 💥💥💥 conflictos por todo lado 💥💥💥.

3. No permite hacer un release de código rápido. Imaginemos que por error, reparamos un bug en el branch equivocado o se se integro al brach equivocado (siguiendo el flujo normal) vamos a tener que volver a crear un pull request, esperar al review, el build, correr los tests, etc., tiempo tiempo tiempo ⏳. O bien simplemente si queremos agarrar lo que se ha desarrollado y hacer un release inmediatamente, no es posible, es muy probable que el código no se encuentre listo para hacerlo.

### ❓¿Qué es trunk-based development?

![Screenshot 2020-10-12 at 4.13.26 PM](https://dev-to-uploads.s3.amazonaws.com/i/wgdfc9047q2d8ri1wfiz.png)
 
Es una estrategia de Git donde existe un trunk(un branch principal, usualmente llamado master/main) en el cual todo el equipo colabora he integra directamente (hace push), siguiendo estas consideraciones:

1. No existen branches de larga duración. No se le da mantenimiento a ningún branch. Por ejemplo en el caso que mencione anteriormente sobre la creación del branch de release (si fuese necesario crearlo) y se encuentra un error, el mismo debe ser reparado en el trunk y luego se haría un nuevo branch de release, pero nunca se le da mantenimiento a ese branch.
Nota: en algunos casos es permitido hacer cherry-pick para mover un cambio, o hacerlo directo en el branch de release, pero se debe de mover inmediatamente al branch de develop.
2. Se debe hacer commit al menos una vez al día (esto no significa que vamos integrar cualquier código solo por hacer commit, el siguiente punto lo explica mejor). Esto lo que busca es eliminar la distancia entre los desarrolladores cuando se empieza a codear cosas nuevas. Estoy seguro que muchas veces les ha pasado que han desarrollado código que alguien más ya había hecho en su branch pero no lo había subido.
3. Todo lo que se le haga commit es código funcional, esto implica que se cumpla la definición de hecho (definition of done), se hayan creado las pruebas necesarias y todo lo que sea requerido para asegurarse que el código no esta introduciendo un bug 🐛. Esto significa que el equipo debe de tener un grado de madurez y responsabilidad alto al  momento de entregar el código.
4. El trunk siempre debe encontrarse en un estado verde y optimo con esto quiero decir listo para hacerle release.

### 😏 ¿Qué beneficio me trae?

Al estar todo el código en un solo branch nos permite:

- Release por demanda, dado que el codigo en el trunk siempre esta listo y en buen estado, deberiamos poder hacer release en cualquier momento.
- Nos evitamos esos grandes conflictos y esos "merges" extra, ej. Cuando se le da mantenimiento al branch de release y esos cambios tienen que ser movidos a develop, es código que ya paso por un proceso de aprobación, volver a tener que hacer code review no tiene sentido, esto representa un gasto de tiempo. Trunk-based development resuelve este problema.
- Los desarrolladores siempre van poder trabajar con el código más reciente.
- El equipo se vuelve mas eficiente  y mas ágil para entregar código.

### 😀 ¿Debo utilizarlo?

Sí, pero tienes que saber:

1. Si la frecuencia con la que haces release es alta, trunk based development es la estrategia adecuada porque el proceso se convierte nada mas hacer el release. 
2. Equipos y productos que ya se encuentran bien establecidos, con sus tiempos y fechas de release bien definidos es probable que no lo necesiten, la simplicidad de GitFlow es suficiente.
3. ¿Se han encontrado en al situacion en la que el encargado de hacer release dice "no hagan merge de nada, vamos hacer code freeze", ¿se han sentido improductivos? es porque ¡lo es! ¿Porque nos vamos a detener? si tenemos una infraestructura y una suite de pruebas fuerte podemos seguir integrando y aumentar la productividad del equipo. 

### 😳 Entonces, ¿En trunk based development no se hace revisión de código o pull request?

Claroooo que si, pero principalmente esta metodología anima que haya más pair programming y no tener que hacer pull requests. En la versión escalada (scaled trunk based development) para equipos más grandes, se permite crear branches de tiempo corto(que no vivan mas de un día) hacerles code review y sean integrados rápidamente. 

![Screenshot 2020-10-12 at 4.23.34 PM](https://dev-to-uploads.s3.amazonaws.com/i/hjg7uxnfs73k5r3c162l.png) 

### ⚠️ Se escucha un tanto riesgoso, ¿cómo me puedo asegurar de no introducir bugs 🐞?

1. Como he mencionado anteriormente, los desarrolladores deben ser responsables de su código y hacer su mayor esfuerzo para subir código de calidad, a su vez darles la confianza para que lo puedan hacer.
2. La automatización es clave para el éxito de esta metodología, con esto me refiero desde unit tests hasta la infraestructura, tener una continua integración (CI), que nos permita hacer pruebas de inicio a fin del nuestro código y así evitar llevar a introducir un error en el app. 
3. Si bien sabemos que se espera que agreguemos funcionalidades completas, esto no implica que una lógica este lista para hacer para ser presentada al usuario final, para esto debemos recaer en el uso de [feature flags](https://dev.to/malvarezcr/que-son-los-feature-flags-kc7), esto quiere decir que se va integrar el código pero vamos a esconderlo detrás de un condicional para mostrarlo hasta el momento que este lista o sea pertinente liberar la funcionalidad. Si quieres saber mas sobre feature flags puedes leer en este [post](https://dev.to/malvarezcr/que-son-los-feature-flags-kc7) en el que explico como se pueden utilizar a nuestro favor.

### 👀 Conclusión

La diferencia más grandes entre GitFlow y Trunk Based Development se encuentra en el scope (ambito) del desarrollo de una nueva funcionalidad, en GitFlow se espera que el desarrollador dure días, semanas hasta meses en entregar su tarea completa, diferente a Trunk Based development en que espera que se entreguen porciones de código pequeñas y se integradas rápidamente al trunk. Existen diferentes "sabores" o modificaciones de esta estrategia, pero el objetivo es el mismo. 

Trunk based development nos permite ser más efectivos y versátiles al momento de hacer releases, pero a su vez requiere que el equipo sea responsable, maduro y que exista automatización que certifique que nuestro código esta en el estado optimo para ser liberado.

### 📕 Referencias

[https://trunkbaseddevelopment.com/](https://trunkbaseddevelopment.com/)

[https://cloud.google.com/solutions/devops/devops-tech-trunk-based-development](https://cloud.google.com/solutions/devops/devops-tech-trunk-based-development)

[https://www.toptal.com/software/trunk-based-development-git-flow](https://www.toptal.com/software/trunk-based-development-git-flow)

—

¿Quieres invitarme a un cafecito?

[![0_qyvuaXnWMWm33Ea8](https://dev-to-uploads.s3.amazonaws.com/i/5t90yzlkmfy7vnth7u58.png)](https://www.buymeacoffee.com/marianocodes)