Lecciones aprendidas usando Git y liberando código
Tags: latam, git, devops, productivity
Published: 2020-11-10 05:41:31

## Introducción 

Nuestro repositorio de código tiene más de 6 años, cada mes agregamos más de 2,000 commits al repositorio, por cierto es un solo proyecto, y daré una charla en el [SG Live Conference](https://sg.com.mx/sgvirtual/live/) de nuestro monolito en PHP... y ese pues es tema de otro blog. 

En este blog post intentaré recapitular algunas de las experiencias y lecciones aprendidas por las que hemos pasado en estos 6 años de desarrollo de software usando Git. 

Mi equipo de desarrollo está ubicado en México, en la bella ciudad de Santiago de Querétaro, yo soy chilango, pero he adoptado a Querétaro como mi nuevo hogar, tanto que aquí nació nuestra hija, quien tiene toda mi atención. 

Este blog post recuerda algunas de las cosas que hicimos cuando estuvimos demasiado tiempo enfocados en las funcionalidades y operación, y adquirimos mucha deuda técnica.

---

## Inicio

**Setup**:
* 🧍DEV: 5.
* 🗓️ release a PROD: 1 vez al mes.
* 🗺️ Estrategia de Git: ninguna, todo a `master` (ahora se dice `main`).


Inicialmente el **release** consistía en: 
* En una máquina local, hacer checkout de `master`.
* Crear una copia del proyecto actual en PROD, como respaldo.
* Subir el código por FTP al servidor de PROD (Producción).
* Ejecutar SQL scripts en PROD server.
* Borrar cache.

El proceso de subir el código tardaba dependiendo del ancho de banda que tuviéramos al momento, y confiábamos en el cliente FTP remplazará todos los archivos correspondientes. 

### Problemas comunes: 
* Algún script no se ejecutaba en PROD y teníamos que ejecutarlo a mano.
* El sistema tardaba varios minutos en estar disponible. 
* Faltaban cambios en `master` debido a que alguien olvidaba hacer un commit, y en su local funcionaba, hacía el commit-push y solo subíamos ese archivo faltante a PROD. 

Estos problemas afectaron poco a nuestros usuarios porque al darnos cuenta de ellos, hacemos el release durante las noches o en fines de semana, que es cuando no teníamos tráfico.

### Mitigación a problemas
* Release durante la noche, o fines de semana.
* Generábamos archivos compartidos para tener los SQL scripts a la mano durante el proceso de release.

## v 1.0 

Creo es importante mencionar que tanto en la etapa anterior como en esta usábamos Gitlab, self hosted, en un droplet de Digital Ocean, las actualizaciones de Linux y de Gitlab nos quitaban tiempo, a veces si Digital Ocean tenia problemas nuestro repositorio no era alcanzable.

**Setup**:
* 🧍DEV: 10.
* 🧍QA: 2.
* 🗓️ release a PROD: Cada 15 días.
* 🗺️ Estrategia de Git: branch por nombre de features y después merge a `master`.


Para poder probar las cosas más seguido ahora teníamos 2 ambientes, uno de develop, uno de staging (pre-producción) y el de producción. En develop muchas veces literal subíamos desde nuestros equipos locales, en staging subíamos el `master` que estábamos preparando para el release. Ese `master` ya tenía cambios preparados. 

Si ocurría un error en PROD, a veces bajábamos esos archivos, los editábamos y subíamos directamente, porque nuestro `master` ya no era limpio. 


### Problemas comunes: 
* Faltaban cambios en `master` debido a que alguien olvidaba hacer un commit, y en algún ambiente si funcionaba, hacía el commit-push y solo subíamos ese archivo faltante a PROD. 
* El server de las aplicaciones de develop y staging eran el mismo, y a veces se subía el código a uno en lugar de al otro.
* A veces los scripts de SQL eran ejecutados en un ambiente incorrecto, nos autosaboteabamos sin querer. 


## v 2.0 

Abandonamos Gitlab en nuestro propio servidor, teníamos problemas de espacio de disco duro, y a veces el mismo server se agotaba en recursos de RAM cuando éramos muchos usándolo. Decidimos contratar Bitbucket porque ya teníamos toda la suite de Atlassian y pues era más fácil agregarlo a la factura. 

**Setup**:
* 🧍DEV: 20.
* 🧍QA: 5.
* 🗓️ release a PROD: Cada 1 o 2 meses.
* 🗺️ Estrategia de Git: Gitflow Workflow.

Decidimos usar el [Gitflow Workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) ahora si ya podíamos mantener `master` limpia, y sin cambios para un release, y creábamos ramas de releases. 

Teníamos un release grande al mes, y usábamos nomenclatura como `2.1`, y releases intermedios en donde a veces se iba uno o dos bug fixes `2.1.1`, en Jira, las tareas y épicas las tapeábamos por número de release, así podíamos ir identificando el alcance de lo que íbamos a lograr liberar. 

Usábamos tags de lo planeado, vs lo liberado, la verdad es que el proceso era engorroso, me sentía hablando en clave, diciendo `v.3.14.16` y cosas así. En cada release siempre quedaban osas pendientes de liberar. 

Ahora teníamos como 5 ambientes de develop, en donde subíamos las ramas de los features para que los analistas QA pudieran hacer pruebas previo su merge a la rama del release correspondiente. 

### Problemas comunes: 
* El control de scripts de SQL por versión de release era complejo. 
* A veces teníamos tantas ramas de versiones abiertas, que era muy complejo pensar en un revert. 

---
Pausa
---

Hasta este punto, algo que normalmente terminábamos haciendo es que después de cada release, ejecutábamos un set de pruebas manuales en el sistema en producción para asegurarnos que no habíamos roto nada. Ese proceso nos llevaba normalmente unas 2 o 4 horas. 

Nuestro sistema ya tenía más de 30 o 40 módulos, y nos enfocábamos a los 10 más usados, y a lo demás le echábamos la bendición, de vez en cuando rompíamos algo de otro módulo y tardábamos algo en darnos cuenta. 

Cada release era un proceso pesado, en donde los que aportaban código y los analistas de QA debían de estar al pendiente de que todo hubiera sido exitoso.

Todos los deploys eran usando FTP. 

---

## v 3.0 

**Setup**:
* 🧍DEV: 30~.
* 🧍QA: 10.
* 🗓️ release a PROD: 1-10 veces al día.
* 🗺️ Estrategia de Git: [Git Feature Branch Workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow).

Decidimos dejar de usar FTP, y empezamos a programar pipelines en Bitbucket, que hicieran el deploy (release) a los ambientes que desearemos, eso le dio tiempo a los líderes técnicos que eran quienes normalmente _deployaban_ dependiendo de las necesidades de sus DEVs, esto ayudo a que se pudieran enfocar más en la calidad del código y de los features. 

Además iniciamos el proceso de agregar pruebas automatizadas al proyecto, unitarias, funcionales y de Selenium. Así antes de hacer el _deploy_ se podía validar si el proyecto seguía funcionando correctamente. 

Los sql scripts dejaron de estar en un archivo compartido, ahora se ejecutaban a través de _Migrations_ que las ejecutaban en el server correspondiente al hacer el _deploy_. 

Cada que se validaba un feature o un bug, se hace rebase, se hace `merge` a `master` y se ejecuta el release a producción.

---

Cuando trabajamos con versiones y releases era más común que intentáramos replicar un proceso de sprints de Scrum, ahora con los procesos más sueltos, un tablero Kanban en Jira nos permite llevar mejor control de las tareas que se están acercando a liberarse en producción.

El tema de las metodologías es para otro blog post.

---


## Cierre 

Espero que este blog post motive a más líderes técnicos de LATAM a compartir sus lecciones aprendidas con las comunidades que están ávidas de conocimiento, como decía (Osvaldo)[https://twitter.com/omercadocoss] en su [post](https://omercadocoss.medium.com/latam-necesitamos-m%C3%A1s-stand-up-y-m%C3%A1s-tech-a55ffadd8eee), y como decía [Vicente](https://twitter.com/xnt) en nuestro [podcast](https://anchor.fm/chilemoleytech/episodes/E31---Creando-Equipos-en-Tech-ft--Vicente-Plata-devzcommunity-em33h2), los líderes debemos ser más humildes en compartir nuestras experiencias, y pienso que dejarlas escritas ayuda a que más personas las encuentren.