# Gitflow

El control de versiones lo gestionamos con git. Esta maravillosa herramienta desarrollada con Linus Torvalds nos permite trabajar en equipo e ir gestionando los cambios al código. Pero, ¿cómo lo usamos?

En Accionet seguimos la metodología GitFlow. Por si no la conocen dejamos unos artículos que pueden ser de interés:

En simple gitflow define cúando crear una rama (branch) y cómo gestionar las distintas ramas para minimizar conflictos.

# Branches

En concreto lo que Gitflow propone es 2 branches principales:

  • master: Esta es la branch principal y debe contener el mismo código que está en producción actualmente.
  • develop: Esta es la branch donde están todas las cosas que están "listas" para producción. Para rapidez de tecleo, en Accionet a esta la llamados dev.

Nunca desarrollamos o escribimos código directamente en una de estas branches. Para desarrollar existen dos "familias" de branches:

# Feature Branch

# Función

Cuando tenemos que hacer una nueva funcionalidad, creamos una nueva branch. Siempre hacer 1 funcionalidad por cada branch. No acumular funcionalidades en una branch.

# Salir desde

Siempre salir desde dev jamás desde master:

git checkout -b myFeature dev

# Volver A

Una vez que hayamos desarrollado la funcionalidad y testeado adecuadamente, debemos hacer una Pull Request a dev no a master.

# Convención de Nombre

En Accionet no tenemos una convención de nombre muy estricta sobre cómo se debe llamar cada branch. Pero como regla general:

  • En lo posible, evitar nombres largos.
  • Evitar nombres solo con número o alguna codificación que no tenga relación directa con lo desarrollado.
  • Auto descriptivo, que con el nombre de un indicio sobre lo que se está desarrollando.
  • Nombres en Inglés.

JAMÁS HACER

En rojo y grande, un práctica muy común que se debe evitar es nombrar las branches según quién es el desarrollador. Si Juan va a desarrollar una funcionalidad, que la branch no se llame "Juan".

# No Hacer
git checkout -b addImagesToProfileOfUser dev   # muy largo
git checkout -b 12345 dev   # solo números
git checkout -b feature12345 dev    # no es auto descriptivo
git checkout -b agregarImagen dev   # en inglés
git checkout -b juan dev   # indicar qué, no quién
# Hacer
git checkout -b profileImages dev

# Hotfix Branch

# Función

No todos los cambios al código son nuevas funcionalidades. Si se debe arreglar un typo, bug u otro, se hace a través de una hotfix branch. Mantener estas branches chicas, solo deben arreglar el error puntuar que se busca corregir.

# Salir Desde

Usualmente desde master. Si el error fue encontrado en dev y todavía no está en master entonces se puede salir desde dev.

# Volver A

Se debe volver desde dónde se salió. Es decir si se salió de dev, se debe volver a dev, si se salió desde master se debe volver a master. En este último caso, luego se debe actualizar dev, para que dev esté al día con master.

Regla de Oro

Todo el código que está en master debe estar en dev a todo momento.

# Convención de Nombre

La misma convención de nombre que aplica para Feature Branch. La única excepción es que se debe empezar con la palabra "hotfix". Por ejemplo:

# No Hacer
git checkout -b fixTypoLogin master
# Hacer
git checkout -b hotfixFixTypoLogin master
git checkout -b hotfix-fixTypoLogin master

# Merge a Master

Solo se debe mergear a master una Hotfix o bien dev, una vez que esté listo para producción. Bueno, en verdad jamás hacer un merge a master, siempre usar una Pull Request.

# Pull Request + Code Review

Para pasar código a master y a dev siempre lo hacemos a través de Pull Request. Esto nos permite tener control de que no cualquier basura llegue a las branches principales, poniendo reglas, tanto subjetivas cómo objetivas, que nos permitan revisar si cómo equipo aceptamos el cambio o no.

# Continuous Integration

Esto se suele llamar Integración Continua. Citando a wikipedia:

Integración Continua

Es una práctica de ingeniería de software que consiste en hacer integraciones automáticas de un proyecto lo más a menudo posible para así poder detectar fallos cuanto antes. Entendemos por integración la compilación y ejecución de pruebas de todo un proyecto

En concreto, cada vez que se sube un commit a github, se revisan lo siguiente:

  • Test: Revisa que todos los tests pasen. Esto permite detectar fallos tempranamente.
  • Coverage: Cobertura de los tests. Accionet exige un mínimo de cobertura que los tests deben tener. No sirve tener tests si estos no cubren todos los casos.
  • Linter: Revisa los errores de sintaxis y estilo del código. Se permiten warnings pero no errors. Más información sobre el linter acá.

Si alguno de estos arroja un error, no dejará mergear la Pull Request hasta que el error haya sido arreglado. De esta forma nos aseguramos que nuestro código mantenga unos estándares mínimos.

# Branch Actualizada

Además de las condiciones de Continuous Integration, la branch que se está comparando (es decir la que se busca mergear) debe estar al día con la branch base. Es decir todos los commits de la branch base deben estar en la branch comparada.

# Code Review

Todas las reglas anteriores son objetivas, es decir cumple o no cumple. Hay una última condición que es subjetiva y muy importante: Code Review. Un miembro del equipo debe darle el "visto bueno" a la Pull Request, es decir debe revisar el código que se busca agregar y revisar que sea fácil de comprender, que no tenga fallas ni code smells. Esta es una buenísima oportunidad, para tanto el revisador como para el revisado, para aprender el uno y del otro.

# Cada Cuanto Hacer una Pull Request

Hacerle Code Review a una Pull Request muy larga es un infierno. Por lo mismo las Pull Requests deben ser periódicas, concisas y cortas. Pero esto no se debe forzar, una Pull Request indica que la funcionalidad en cuestión está lista, jamás hacer una Pull Request si la funcionalidad todavía no está lista. Debe hacerse un trabajo conjunto por parte de todo el equipo para dividir las funcionalidades grandes en pequeñas funcionalidad e ir armando de a poco, con varias Pull Requests.

# Commits

# Cuándo

Una difícil pregunta: ¿cuánto y cuándo commitear? Viendo parafraseando la respuesta a esta pregunta:

Cúanto Commitear

Uno no debe hacer commits baso en tiempo, sino que basado en cuando uno agregó o bien arregló algo. Agregaste un método que funciona, arreglaste un typo, arreglaste cosas de estilo, etc.

Como regla general los commits deben ser atómicos, deben englobar un solo cambio. Yo suelo hacer la analogía cuando uno esta trabajando en un archivo Word y decide apretar el botón save. Hacer un commit es equivalente a apretar save, uno no apreta save cada vez que uno ingresa una letra pero tampoco uno escribe un ensayo de 5 planas sin apretar save.

# Formato

Cada commit debe tener un mensaje, si bien en git esto es opcional, ¡en Accionet es obligatorio! Este mensaje debe explicar el cambio que se hizo. Accionet sigue la guía de platanus sobre commits.

Pero en concreto, deben ser en inglés, no muy largos y tener el siguiente formato:

  tipo(contexto): descripción

# Tipo

El tipo corresponde a que se debe el commit:

  • feat: Un nuevo feature
  • fix: La corrección de un bug
  • docs: Cambios en la documentación
  • style: Cambios que no afectan el significado del código (espacios, indentación, etc.)
  • refactor: Un cambio en el código que no agrega una funcionalidad ni corrige un bug
  • perf Cambios en el código que sólo mejoran la performance
  • test: Agrega, corrige o mejora tests
  • chore: Cambios al proceso de build y herramientas auxiliares

# Contexto

Funcionalidad que en global el commit. Opcionalmente se puede agregar un / para indicar el archivo o componente dónde fue el cambio:

  tipo(contexto/componente): descripción

# Descripción

Descripción, no muy larga, de lo que el commit hace. Recordar, siempre en inglés!

# Git Aliases

¿No encuentran verboso que cada vez que tenemos que commitear tengamos que hacer git add . y después git commit -m 'type(contexto): descripcion'?

La solución: git alias. Los alias se usan para crear comandos más cortos que se asignan a comandos más largos. Si corres el siguiente comando:

git config --global alias.ac "! git add -A && git commit -m"

Después puedes hacer:

git ac 'type(contexto): descripcion'

Y hará tanto el git add . como el git commit -m 'type(contexto): descripcion'.

A continuación una lista de aliases que usamos en accionet:

# git update-dev

Para actualizar la branch dev:

git config --global alias.update-dev "! git checkout dev && git pull origin dev"

# git update-master

Para actualizar la branch master:

git config --global alias.update-master "! git checkout master && git pull origin master"

# git da

Elimina todas las branches mergeadas exceptuando master y dev:

git config --global alias.da "! git branch | grep -v "master\|dev" | xargs git branch -d"

# git alias

Para ver todos los alias que has creado

git config --global alias.da "! git config --get-regexp ^alias\. | sed -e s/^alias\.// -e s/\ /\ =\ /"

# git ac

El primero que vimos, para agregar y commitear en un solo comando.

git config --global alias.ac "! git add -A && git commit -m"