Un gated commit, también llamado pre-tested commit, es un patrón de integración en el que un commit no es aceptado en el repositorio sin antes haber corrido una serie de pruebas utiliando el nuevo código. En otras palabras, el commit no se aprueba si alguna de las pruebas falla.

¿Por qué querrías esto? Una integración como ésta hace que tu aplicación sea más robusta al cambio porque ahora corres todas o una parte de tus pruebas antes de que ese nuevo código esté disponible para alguien más.

Voy a mostrarte como implementar este patrón de integración con Git. En este ejemplo, nuestra serie de pruebas unitarias actuarán como el gate que permitirá que nuestros commits lleguen al repositorio



¿Qué necesitas?

  • Git
  • El repositorio Git de tu aplicación
  • Suite de pruebas

Comenzando: Git Hooks

Queremos que nuestras pruebas corran antes de que un commit llegue al repositorio. Git nos permite correr comandos personalizados justo antes de que ese evento ocurra gracias a Git Hooks. No entraré en los detalles del cómo funcionan estos hooks pero, convenientemente para nosotros, existe un hook llamado pre-commit. Éste hook es ejecutado justo antes de que ocurra un commit. Es el lugar perfecto para correr nuestra suite de pruebas.

Configurando un pre-commit hook

En tu repositorio de Git, existe una carpeta oculta llamada .git en la cual se almacenan los hooks. Si nunca has modificado ningún hook, tu directorio .git se verá como este:



Para crear nuestro hook, necesitamos agregar un archivo llamado pre-commit (sin extension) dentro del directorio hooks. Vamos a crearlo. La única cosa que el archivo tiene que contener es el comando utilizado para correr la suite de pruebas. No olvides dar permisos de ejecución al archivo (chmod +x).

Si utilizas Ruby en tu aplicación, probablemente corras tus pruebas utilizando rake. Si ese es el caso, to archivo pre-commit se verá como este:

rake test:units

O si estás dentro de la ola de JavaScript, probablemente puedes tener esto en tu archivo:

npm tests

Independientemente del lenguaje/framework que utilices, tu hook de pre-commit tiene que tener un comando para correr tus pruebas. Y, mientras el comando de tu hook regrese un código que no sea cero, el hook permitirá que el código llegue al repositorio. De lo contrario, el commit será rechazado.

Prueba de fuego

En este punto ya puedes hacer un commit y observar como corre la suite de pruebas (y esperemos pase), abriendo así la compuerta para que nuestro commit llegue al repositorio sin ningún inconveniente.

En el siguiente ejemplo yo utilizo una aplicación de Grails, y el hook de pre-commit contiene este código:

grails test-app -unit

(Toca la imagen para repetir)

Éxito! 🎉

En caso de que algunas de las pruebas falle:

Cara triste ☹️

Resumen

Acabamos de crear un hook de pre-commit en Git que contiene comandos específicos para ejecutar una serie de pruebas unitarias en nuestra aplicación. Ahora, cada que hagamos un commit, nuestras pruebas correrán. Si las mismas pasan, tendremos un commit exitoso; si no, el commit es rechazado.

Puedes extender la funcionalidad del hook de pre-commit para construir algo tan complejo como necesites. Puedes, por ejemplo, correr una herramienta de linting para asegurarte que los estilos y formatos de código cumplan ciertas reglas. O puedes llevarlo al siguiente nivel e integrarlo con tu proceso de Continuous Integration utilizando hooks adicionales.