Recientemente, tuve la oportunidad de realizar una presentación sobre el uso correcto de GitLab y se me ocurrió que podía usar una buena parte del material para mostrarte cómo usar un flujo de trabajo robusto independiente de la plataforma que uses. 

¿Qué es GitFlow?

Es un flujo de trabajo basado en Git que brinda un mayor control y organización en el proceso de integración continua.

 

¿Por qué implementarlo?
  • Aumenta la velocidad de entrega de código terminado al equipo de pruebas.
  • Disminuyen los errores humanos debido a los merges.
  • Elimina la dependencia de funcionalidades al momento de entregar código para ser puesto en producción.
¿Cuándo se recomienda implementarlo? 
  • El proyecto tiene cambios frecuentes y se requiere actualizar el ambiente de producción garantizando continuidad en la operación.
  • El proyecto tiene un nivel de complejidad considerable.
  • Se desea tener un proceso de soporte a errores efectivo con actualizaciones rápidas.

Gitflow es ideal para los proyectos que tienen un ciclo de publicación cíclicos o requiere cambios frecuentes en producción.

Gitflow define un modelo estricto de ramificación diseñado alrededor de la publicación del proyecto. Proporciona un marco sólido para gestionar proyectos más grandes.

En GitFlow vamos a usar dos ramas principales que van a almacenar nuestros cambios en la historia del proyecto.

Estas dos ramas son la rama develop (graficada en azul) y la rama master (graficada en verde).

En la rama master, guardaremos el historial de versiones de la aplicación mientras que la rama develop nos servirá para mantener un registro de las features que se han integrado a nuestro proyecto

Las ramas master y develop, son las únicas que mantienen su ciclo de vida a lo largo de todo el proyecto.

Sin embargo estas ramas se encuentran protegidas, es decir, solamente miembros del repositorio con permisos elevados pueden aprobar que un commit se añada a una de estas ramas. 

 

Por qué proteger mis branches?

Las ramas protegidas aseguran que tus colaboradores o integrantes del repositorio no hagan cambios irreversibles en tu producto

Las ramas Feature

Llamadas así porque su existencia supone una nueva funcionalidad a nuestro producto.

Las ramas feature son la base del desarrollo. Pueden constituir una nueva funcionalidad, un bugfix, e incluso un refactor.

El objetivo de tener ramas feature es aislar el código WIP (Work in Progress) de la rama estable develop mientras se está diseñando o agregando nuevo código.

Una vez que el developer haya terminado su feature, estará listo para unir sus cambios en la rama develop. El escenario se puede visualizar en la siguiente imagen: 

La manera correcta de incorporar los commits existentes desde feature a develop, es a través de un Pull Request (PR).

Un Pull Request (PR) es equivalente a un Merge Request (MR).

La diferencia es que los PR pertenecen a la plataforma GitHub y los MR a GitLab.

Una vez que el Mantainer haya realizado el respectivo code review, se procederá a aprobar o cerrar el PR. Hagamos un análisis de qué pasaría en cada uno de los casos:

Aprobando un PR

Si el código satisface la revisión del Mantainer, el PR es aceptado y da como resultado el siguiente flujo:

Rechazando un PR

Si el código contenido en el PR no satisface al Mantainer, el mismo es cerrado. Sin embargo, el developer puede realizar más commits enmendando su error para que de esta manera el PR sea aceptado. En la siguiente imagen veremos cómo el developer agregó un cambio extra para que el Mantainer acepte el PR.

Una vez aprobado, el flujo se vería de la siguiente manera:

Notas:

  • En ambos escenarios, la rama feature es eliminada de origin después d que se acepte el PR.
  • Este procedimiento está normalizado y se considera una buena práctica.
  • Muchas herramientas como GitHub o GitLab permiten realizar esto de manera automática. Aprovecha este feature para mantener tu repositorio limpio.

La rama release

Cuando los suficientes cambios se hayan realizado a nuestra rama develop, llegará el momento de realizar una versión para entregar al cliente.

Hacer un release usando GitFlow  permite congelar funcionalidades para generar un nuevo release. Para ello, generaremos una rama llamada release con base en develop.

Este es el momento perfecto para introducir el siguiente concepto:

 

Isolate Fix Merge

Aislar - Estabilizar - Mergear

En todos los flujos que veremos sobre GitFlow, encontraremos este mismo patrón.

Asegúrate de aplicarlo ya que te permitirá mantener tu repositorio limpio y estable.

Para aislar el cambio, lo colocaremos en la rama release. Tu flow debería verse algo así:

El objetivo de aislar el commit, es permitir que el desarrollo siga su rumbo mientras tú estabilizas el cambio antes de que llegue a producción.

Como ejemplo, imaginemos que al pasar por el proceso de manual testing, se encontró un bug:

Al crear esta rama, se inicia el siguiente ciclo de publicación, por lo que no pueden añadirse nuevas funcionalidades (features) tras este punto; solo las soluciones de errores, la generación de documentación y otras tareas orientadas a la publicación deben ir en esta rama.

Una vez que hayas solucionado el error, puedes generar una versión de producción haciendo merge a master.

No olvides también hacer merge a develop para evitar que ese bug vuelva a aparecer:

Utilizar una rama específica para preparar publicaciones hace posible que un equipo perfeccione el release actual mientras otro equipo sigue trabajando en las features para el siguiente release. Asimismo, crea fases de desarrollo bien definidas

La rama hotfix

Las ramas hotfix se utilizan para reparar rápidamente los releases de producción. Las ramas hotfix son muy similares a las ramas de release y a las de feature, salvo porque se basan en master en vez de la de develop.

Tener una línea de desarrollo específica para la solución de errores permite que tu equipo aborde las incidencias sin interrumpir el resto del flujo de trabajo ni esperar al siguiente ciclo de publicación.

Como puedes ver, la rama hotfix nace en la rama master, soluciona el inconveniente y se vuelve a incorporar a master como una versión mejorada de la anterior.

No olvides hacer merge a develop para que el error no vuelva a aparecer en el futuro.

En resumen, el flujo general de Gitflow es el siguiente:

  1. Se crea una rama develop a partir de master.
  2. Una rama release se crea a partir de develop.
  3. Las ramas feature se crean a partir de la develop.
  4. Cuando una rama feature está completa, se incorpora a develop.
  5. Cuando la rama de release está lista, se fusiona con developmaster.
  6. Si se detecta un bug en master, se crea una rama hotfix a partir master.
  7. Una vez que hotfix está estabilizada, se fusiona tanto con develop como con master.

En conclusión:

GitFlow es un modelo que al igual que el resto, dependerá de tu disciplina y colaboración de equipo para que funcione de manera correcta. Sin embargo, las reglas que GitFlow sugiere no son absolutas. Existen reglas que no están escritas y si tu cliente solicita versiones de una manera “especial”. Probablemente tendrás que adaptar tu flujo a ello.

Por suerte, Git es una herramienta muy versátil que permite que se realicen cambios con relativa facilidad. Dependerá de tí entonces, mantener tu repositorio limpio y en armonía tanto para que tú como tu equipo puedan mantenerse productivos.

 

Mi recomendación para ti:

El autor de GitFlow, Vincent Driessen, escribió también un cli que integra la mecánica de gitflow en tu terminal. Si deseas trabajar con ella, te recomiendo que revises su documentación en su repositorio de GitHub.

Si tu arma de preferencia es Eclipse, encontré este complemento que podría ayudarte (link aquí).

Sin embargo, mi recomendación por ahora es que trabajes sin un cliente específico. Haz tus PR, entiende el flujo y posteriormente (y solamente con el objetivo de ahorrar tiempo) instala un complemento.

Eso es todo en esta entrada. En futuros posts veremos un ejemplo práctico con el cual podrás jugar y familiarizarte con este flujo.

Gracias por pasar por aquí. No olvides dejarme tu comentario.