Git es una buenísima herramienta para llevar un control exhaustivo de las versiones de nuestro código. Es indispensable para cualquier proyecto, independientemente del lenguaje o tecnología que se esté usando…
Todo es muy bonito hasta que de repente hay varias personas haciendo commits, merges, ramas, etc. en el mismo repo y todo se vuelve un lío. No te preocupes, todos hemos estado ahí, hay variedad de flujos de trabajo (Workflows) con Git que nos facilitarán la vida para que nuestro repo no sea caos y destrucción.
Los siguientes flujos se adaptan a diferentes situaciones. Todos ellos permiten adaptaciones y modificaciones. Parte de la gracia es hacer variaciones en el que elijamos para adaptarlo a nuestro equipo y proyecto.
Git Flow
Git Flow es un flujo de trabajo de los más utilizados. Es más complejo que el resto de workflows y funciona muy bien si existe una buena organización en el equipo. Permite a los desarrolladores trabajar de manera organizada y colaborar de manera eficiente. Y es adecuado para proyectos donde se necesita una estricta separación entre desarrollo, pruebas y producción.
Tiene dos ramas principales, Master y Develop. En master solo hay versiones estables del software. Develop es la rama principal de desarrollo, donde se irán integrando todos los cambios. Para trabajar en nueva funcionalidad crearemos una rama con el prefijo feature/ partiendo de la última versión de Develop. Una vez commiteados nuestros cambios abriremos una Pull Request (PR) contra Develop, que después de pasar por test y por revisión la integraremos.
Antes de integrar nuestros cambios en la rama de producción (Master) abriremos una rama Release desde Develop con el nombre de la versión que le corresponda, por ejemplo “release/V1.33”. Esta rama nos servirá para dar los remates finales antes de llevar a producción toda la nueva funcionalidad. Una vez hecho esto se integra en Master y se le asigna una etiqueta con la versión.
Si por cualquier motivo se ha colado un bug en producción, lo resolveremos creando una rama HotFix que partirá de Master y luego la integraremos de vuelta, no sé nos tiene que olvidar llevarnos el HotFix también a Develop para no volver a llevar el bug a producción en la siguiente release.
Git Flow es el estándar actualmente y está muy bien definido, pero el principal problema es que incrementa la complejidad del repositorio bastante y en ciertos escenarios en los que el equipo es reducido o que el proyecto es pequeño puede volverse un inconveniente más que una ayuda.
Git Hub Flow
El segundo flujo es Git Hub Flow. Sigue una metodología de Trunk-based development (TBD) que se basa en tener solo una rama principal que es Trunk o Master, en este caso es Master pero lo mismo da que da lo mismo. El flujo funcionaria de tal manera que nosotros crearíamos nuestra rama feature y después de haber realizado nuestros cambios abrimos una PR contra Master.
Pero antes de que la integremos, haremos test y la desplegaremos en producción. Que no cunda el pánico, si ocurriese cualquier problema en producción se vuelve a desplegar Master que siempre es muy estable. Una vez realizado el testing final en producción se integraría en la rama principal y se vuelve a desplegar Master.
No hay rama release, cada cambio va a producción directamente después de que hagamos tests. Esto disminuye el riesgo de cada despliegue ya que solo se integra y testea una funcionalidad a la vez.
Para las ramas HotFix se sigue el mismo proceso que una feature normal.
En GitHub se pueden configurar las Git Hub Actions para personalizar nuestra integración continua. Podemos configurar que, por ejemplo, cuando se haga una PR se ejecuten los test y se haga el deploy de la feature.
Al tener solo la rama Master como principal puede volverse un lío porque todos los cambios los realizamos sobre ella.
En resumen, GitHub Flow es una metodología simple y flexible que se puede adaptar a diferentes entornos de trabajo. Funciona mejor en proyectos donde el equipo es pequeño, el lanzamiento es menos crítico y donde se libera código con frecuencia.
Git Lab Flow
El equipo de Git Lab también nos trae su flujo de trabajo, Git Lab Flow. Es muy parecido al Flow de Git Hub pero la principal diferencia es que hay una rama para cada entorno.
Para desarrollar una feature seguimos el mismo flujo que antes, creamos la rama partiendo de Master, realizamos nuestros cambios y abrimos una Merge Request (MR), igual que abriríamos una PR. Se realizan pruebas antes de ser integrada pero no se despliega en producción. Tendremos que abrir una MR para cada rama/entorno, y tiene que ser revisada una por una.
Un HotFix es igual que una feature salvo que cuando es integrado en Master se integra en el resto de los entornos mediante Cherry pick.
Git Lab Flow requiere una muy buena organización y comunicación entre los miembros del equipo. Es útil para proyectos en los que queremos que el código que haya en producción sea muy muy estable. Cada cambio va a pasar múltiples revisiones. Y donde queramos tener un mayor control sobre las versiones y la capacidad de mantener distintas versiones para cada entorno.
Release Flow (Microsoft Flow)
El penúltimo flujo es Release Flow, también conocido como Microsoft Flow ya que nos lo trae el equipo de Azure. Es un flujo Trunk-based development y la principal diferencia es que en vez de tener features tenemos topics. Un topic es una pequeña feature que implementa poca funcionalidad. Crearemos nuestro topic partiendo de Master y una vez realizados nuestros cambios abriremos la PR. Al ser una rama con poca funcionalidad permite hacer rápidamente el Code Review y la integración en la rama principal.
Sí que hay rama release que será abierta una vez haya terminado el sprint, que en el caso de Azure será a las tres semanas. La release lleva en el nombre el número del sprint correspondiente, en el sprint 129 la rama release se llamará release/M129. Una vez esté todo listo en nuestra rama release, la desplegaremos en producción.
Si fuese necesario hacer un hotfix se crea partiendo de Master y se integraría primero en Master y luego en la release para evitar que solo sea integrado en release y no en Master. Si el bug ya no existe en Master sí que se integra directamente en la rama release. Una vez pasadas otras tres semanas otra release es creada y la anterior es, por normal general, borrada y dejada en el olvido.
¿Y qué pasa si se habré una release con nuevas funcionalidades sin terminar? Esto es totalmente posible ya que como hemos visto las release se abren en un momento del tiempo concreto no en un punto del desarrollo, no al acabar n nuevas funcionalidades se saca una release. Pues el equipo de Azure soluciona esto utilizando las Feature Flags, que se pueden configurar de múltiples maneras, ya sea poniendo una variable en el código o en un archivo de configuración para así poder activar y desactivar esa funcionalidad cuando corresponda.
La idea de Release Flow es que se estén integrando cambios todo el rato para así evitar las integraciones con muchos conflictos por culpa de trabajar en ramas paralelas durante un periodo prolongado de tiempo. Se recomienda para proyectos con una estrategia de lanzamiento clara y un proceso de pruebas y validación bien establecido.
Single Branch Flow / Only Master Flow
Por último, vamos a ver el Single Branch Flow o Only Master Flow. En este flujo todo ocurre en master, todo todo. La idea es clonarlos el repositorio del proyecto, implementar la nueva funcionalidad y una vez hayamos terminado haremos el commit y subiremos los cambios al repositorio en remoto.
Este flujo de trabajo no es recomendable para proyecto grandes y donde hay un gran volumen de cambios en el código, ya que puede provocar muchos conflictos y dolores de cabeza. También es importante que las tareas y las planificaciones de estás estén bien estructuradas, para evitar que dos personas realicen dos tareas parecidas y acaben pisando los cambios del otro sin quererlo.
WorkFlows aparte
Una cosa a la que también hay que tener muy en cuenta para qué nuestro repo quede impoluto es los nombres que le damos a nuestros commits. Si no los nombramos bien puede ser un infierno entender porque se ha realizado un cambio, y si además el commit modifica un montón de archivos va a ser imposible saberlo. Un buen nombre debe ser descriptivo y específico, para que cualquier persona que revisa el historial pueda entender de manera rápida y fácil qué se ha cambiado y por qué.
En definitiva, cada flujo de trabajo tiene sus particularidades, y dependiendo del tipo de equipo y proyecto que tengamos unos se adaptaran mejor que otros para ayudarnos a tener el repositorio bien ordenado.