Entrega continua con la potencia extra de Git

Ahora que Git ha acabado con los problemas de la fusión, los flujos de trabajo de ramificación son mucho mÔs atractivos.

Todos hemos oído decir que hay que tener "cuidado con el código escrito por una sola persona" y conocemos las ventajas de hacer software en equipo, ya que se combinan diferentes formas de pensar, formaciones y experiencias... Y, al reunir esas diferencias para resolver cualquier problema, el software termina siendo mejor. Es mÔs fÔcil de mantener, de mayor calidad y, en última instancia, mejor para el usuario.

Colaboración en equipo | CI/CD de Atlassian

Pero también sabemos otra cosa: ”el desarrollo en equipo puede ser un caos!

Hay que saber en qué fragmentos de código estÔ trabajando cada uno, asegurarse de que los cambios no entren en conflicto, adelantarse a los clientes en la detección de errores y mantener a todos conectados con el proyecto y a la última de los progresos. Lo cierto es que todos estos problemas pueden abordarse o con las ramas de Git o con la entrega continua.

Mi intención es mostrar que, al combinar estas dos estrategias (y, si te apetece, incluir alguna herramienta mÔs a la receta), tendrÔs una fórmula de potencia extra para el éxito. 

La eficacia de los flujos de trabajo basados en ramas

A decir verdad, no es que Git sea de por sí perfecto para la entrega continua, sino que los flujos de trabajo de ramificación son idóneos para CD, y Git es idóneo para los flujos de trabajo de ramificación. AdemÔs de ser el complemento perfecto para CD, los flujos de trabajo de ramas y fusiones permiten resolver errores espinosos, probar nuevas tecnologías o, sencillamente, programar una nueva función desde cero sin el riesgo de que tus cambios impidan que el resto del equipo avance con sus propias tareas.

Diagrama de flujo de trabajo bƔsico | CI/CD de Atlassian

Subversion y otros sistemas de control de versiones tradicionales también permiten trabajar con ramas, estÔ claro. Sin embargo, en este punto vamos a conocer al gemelo malvado de la ramificación: la fusión.

Los sistemas tradicionales de control de versiones como Subversion no son eficaces a la hora de hacer un seguimiento de versiones de archivos de diferentes ramas y, cuando llega el momento de fusionar, Subversion tiene que hacer un alto y pedir muchas indicaciones. (Ya sabes... esa ventanita emergente que te pregunta: "¿Quieres tener esta línea o aquella en la versión fusionada?"). Al hacer falta tanta intervención humana durante las fusiones, los equipos tienden a congelar código para que, al hacer la fusión, no les interrumpan los cambios que entran en una rama. Y congelar el código resulta caro, porque es un tiempo bastante improductivo.

Git, por otro lado, es muy bueno en el seguimiento de cambios en diferentes versiones de archivos de diferentes ramas, y siempre sabe cómo era el antepasado común de cada archivo. Es como si tuviera un GPS integrado que le permite navegar por fusiones sin tener que parar a pedir indicaciones todo el tiempo.

Con Git, puedes sacar todo el partido de la ramificación de una manera impensable con Subversion. La carga de trabajo ligada al trabajo con ramas y fusiones es tan pequeña que crear ramas para solo un par de días no solo es factible, sino prÔctico.

Vale, de acuerdo. Pero, ¿por qué es tan eficaz crear ramas para la entrega continua?

Con las ramas, las ramas principales se mantienen limpias y listas para publicar

Como hemos visto, las ramas de corta duración son una forma excelente para que los desarrolladores colaboren en un proyecto o función sin poner trabas a los demÔs. AdemÔs, y mÔs importante en relación con la CD, al aislar el trabajo en curso en ramas de desarrollo, la rama principal y las ramas de versiones estables se mantienen limpias y se pueden lanzar en cualquier momento.

Esto significa ejecutar toda la batería de pruebas automatizadas en las ramas de desarrollo, para que los desarrolladores tengan información útil sobre la calidad de su código y puedan decidir con fundamento cuÔndo se pueden fusionar los cambios. (Si aún no haces pruebas automatizadas, consulta esta entrada de RebelLabs, con consejos e información para elaborar tus primeras pruebas unitarias).

También significa usar las solicitudes de extracción de Git como una forma de revisión de código para que así todo el equipo confíe en la capacidad de mantenimiento e interoperabilidad del código con otras Ôreas del código base. Sí, supone mÔs trabajo inicial que los modelos de entrega tradicionales. Y sí, merece la pena.

Para una buena entrega continua, las ramas de publicación deben estar siempre limpias.

Por ejemplo, todos los equipos de desarrollo de Atlassian tienen acordado que nada se introduce mediante confirmación directamente en la rama principal ni en las ramas estables. Todo el trabajo se hace en ramas. De hecho, somos tan fanÔticos de las ramas que hemos optado por crear una rama independiente para cada incidencia de Jira que abordamos (luego veremos esto).

De esta forma, ”la gente puede romper tantas pruebas y hacerles tanto daño a sus ramas como quiera! La rama principal siempre estÔ lista para la publicación y permite crear nuevas ramas sin heredar un montón de código roto. Eso es todo un plus para la productividad de los desarrolladores en CD y en general (por no hablar de lo positivamente que afecta a su estado de Ônimo).

Las ramas ayudan a aceptar contribuciones externas al equipo

Con la capacidad de ramificación de Git (especialmente la capacidad de bifurcar repositorios completos), es muy sencillo incorporar contribuciones de personas externas al equipo: contratistas, desarrolladores de empresas asociadas, desarrolladores de otras unidades empresariales, etc. Ya no te quitarÔ el sueño tener a personas que no estÔn familiarizadas con tu código base haciendo cambios en ramas críticas y desbaratando tu capacidad de lanzar código nuevo.

Como en tantas otras cosas, unas rigurosas pruebas automatizadas en ramas o repositorios bifurcados son la clave para una buena colaboración. Antes de aprobar una fusión en la línea de código principal, querrÔs revisar los resultados de las pruebas y la compilación.

Consejo de experto

Los gestores de repositorios como Bitbucket permiten usar hooks de Git para garantizar el cumplimiento de los estÔndares de calidad. Por ejemplo, puedes establecer una regla que deben cumplir todas las compilaciones de rama para aceptar y fusionar una solicitud de extracción de cambios.

Una buena ramificación da claridad para el seguimiento del proyecto

Ahora estÔ de moda crear una rama de desarrollo para cada historia, corrección de errores o tarea (por ejemplo, cada incidencia de Jira) que se implementa. En Atlassian, adoptamos este modelo de rama por incidencia hace unos años, ”y no nos hemos arrepentido! Lo que es mÔs, también se ha hecho muy popular entre nuestros clientes.

Al crear una rama para cada incidencia, es muy sencillo elegir a mano los cambios que hay que lanzar a la producción o agrupar en una publicación. Al no acumular una gran cantidad de cambios en la rama principal, se puede seleccionar lo que se incorpora a esta y cuÔndo se hace. Puedes lanzar el MVP de un epic y un cambio "deseable", en lugar de esperar a que todos los cambios "deseables" estén terminados. Si lo prefieres, también puedes lanzar una sola corrección de errores y hacerlo en el marco de trabajo de una publicación habitual. Aunque la corrección sea urgente, para sacar los cambios no tendrÔs que hacer malabares para respaldar todos los que todavía no estén listos para el lanzamiento.

Esa facilidad de lanzar un solo cambio de código es la esencia de entrega continua.

Este concepto mantiene el código no probado fuera de la rama principal. AdemÔs, si incluyes el nombre o las iniciales del desarrollador o la clave de la incidencia de Jira en el nombre de la rama, podrÔs conocer el estado de desarrollo de cada incidencia en curso.

Bitbucket commits git repo screenshot | Atlassian CI/CD

Sigue la convención de nomenclatura de la imagen anterior: es la clave única de la incidencia de Jira que se estÔ implementando y una descripción breve y legible de la incidencia. Un gestor de publicaciones o cualquier otro interesado podría ver el repositorio de arriba y saber de un vistazo que la historia de usuario rastreada por AMKT-13952 estÔ lista para publicar, ya que se ha fusionado con la rama principal. Esto sí que es trazabilidad sin esfuerzo manual.

Entonces, ¿cómo funcionan Git y el flujo de trabajo de entrega continua?

”Buena pregunta! Aquí voy a explicarlo por encima, ya que hay otros artículos se ocupan con detalle de cada fase.

  • Crea una rama para la incidencia en la que vas a trabajar. Incluye la clave de incidencia de Jira en el nombre de la rama para que quede claro para quĆ© sirve. AdemĆ”s, si utilizas otras herramientas de Atlassian como Bitbucket o Bitbucket Pipelines, recogerĆ”n esa clave y crearĆ”n enlaces entre la incidencia, la rama, todas las confirmaciones, compilaciones, solicitudes de incorporación de cambios e implementaciones relacionadas con la incidencia. En otras palabras, las claves de incidencia son mĆ”gicas.

  • Haz los cambios en la rama. Este es tu mundo, asĆ­ que haz lo que te plazca. Prueba cosas nuevas o rompe lo que sea. No importa, porque luego…

  • Pon tu rama en CI. Tu equipo y tĆŗ deberĆ©is decidir si ejecutar pruebas especializadas como pruebas de carga o pruebas integrales basadas en IU, y si desencadenar automĆ”ticamente una ejecución de prueba cada vez que se envĆ­en cambios a la rama. Los equipos de Atlassian suelen ejecutar pruebas a nivel de unidad e integración en las ramas de desarrollo.

  • Actualiza la rama con los Ćŗltimos cambios de la ramaĀ principal de manera frecuente. Puedes hacerlo fusionando mediante cambio de base o con el procedimiento de confirmación de rama. TĆŗ eliges. (Eso sĆ­, recuerda no fusionar mediante cambio de base una rama que compartas con otros desarrolladores: no les harĆ” mucha gracia.) De cualquier manera, detectarĆ”s conflictos de integración antes de la fusión, lo que tambiĆ©n te servirĆ” para mantener limpia la ramaĀ principal.

  • Crea una solicitud de incorporación de cambios cuando estĆ© todo listo para la fusión. Esto significa que la implementación ha terminado, que has incorporado cambios de tus compaƱeros de equipo, que has resuelto los conflictos resultantes y que se han superado todas las pruebas en la rama.

  • Fusiona e implementa como te apetezca. Algunos equipos prefieren lanzar automĆ”ticamente cada cambio en cuanto se fusiona con la rama principal y se superan todas las pruebas; este es el modelo de implementación continua. Otros equipos prefieren que la decisión sobre quĆ© cambios se deben lanzar y cuĆ”ndo no sea automĆ”tica, sino humana. La elección es tuya y de tu equipo.

Automatización de CI de Git | CI/CD de Atlassian

En conclusión...

Ahora toca tomarla. Con los flujos de trabajo de ramificación, la entrega continua es una propuesta mÔs sencilla y Git acaba con los dolores de cabeza de la ramificación. Sigue leyendo y aprende a configurar tu repositorio de Git para que facilite la CD y a poner todas estas ideas en prÔctica con las herramientas de Atlassian. ”Nos vemos en la siguiente pÔgina!

Recomendado para ti

La comunidad de DevOps

PruƩbalo gratis