Durante el ciclo de desarrollo, necesitamos guardar prácticamente de forma obligatoria el código fuente de nuestro software en un repositorio de código para no perderlo ante eventualidades. Siempre bajo un software que controle las versiones, habitualmente en git sea en github, gitlab, o cualquier otra plataforma de desarrollo colaborativo.

Como bien debes de saber, cuando realizamos alguna modificación digna de ser llevada a nuestro repositorio remoto, realizamos el commit de dichas modificaciones para posteriormente hacer el push. Es en esos momentos en los cuales podemos ejecutar procesos para realizar tareas como formatear el código, chequear que esté bien escrito (lint), ejecutar los tests, versionar, …

Esos momentos de los que te hablo entran en marcha los git hooks. En nuestro caso, nos centraremos en los hooks del lado cliente (porque sí, existen hooks en el lado del servidor) y aún más concretamente en los hooks del flujo de commits (Committing-Workflow Hooks).

Git hooks

Como ya has intuido, el git hook (o gancho traducido literalmente) activa un script personalizado cuando ocurren ciertas acciones importantes. Algunos de los «commit hooks» más comunes son:

  • pre-commit: Se ejecuta antes de confirmar los cambios, aunque se puede omitir con un flag –no-verify (git commit –no-verify). Usos: para chequear calidad de código (lint), ejecutar tests, …
  • prepare-commit-msg: Se ejecuta antes que el editor de mensajes de commits se levante pero después de que el mensaje por defecto se haya creado. Usos: para realizar alguna acción de transformación sobre el mensaje.
  • commit-msg: Para validar el estado de su proyecto o el mensaje de confirmación antes de permitir que se realice un commit como por ejemplo que el mensaje cumpla un patrón requerido.
  • post-commit: Se ejecuta después de realizar el commit. Usos: generalmente, este script se usa para enviar notificaciones o algo similar.

Estos scripts, se tienen que generar en el subdirectorio «hooks», dentro del directorio de git «.git», esto es, en .git/hooks/

Husky

Mediante Husky, esta labor de crear scripts se realiza de una forma más sencilla . En nuestro caso, en el momento de crear este artículo, están por la versión 9, pero veamos cómo lo instalamos de la forma habitual, esto es donde nuestro código está a nivel raíz del repositorio (donde se ubica el «package.json» ó el directorio «.git»). Utilizaremos nuestro ya conocido monorepo.

Instalación

Ejecutamos el comando de instalación de npm para añadirlo en el apartado de dependencias de desarrollo:

npm install --save-dev husky

Inicialización

Inicializamos husky mediante el comando:

npx husky init

Lo que creará una entrada en los scripts del package.json de la siguiente forma:

"prepare": "husky"

Y además generará una carpeta en la raíz de nuestro proyecto llamada «.husky» donde se irán añadiendo los diferentes scripts para cada git-hook. En esta versión añade el script «pre-commit», el cual podemos borrarlo o comentar/borrar el contenido si no tenemos nada que hacer por el momento.

Instalación e inicialización (directorio diferente al raíz)

Si eres de los que en tu repositorio no coincide el directorio de git «.git» con el «package.json» en la misma carpeta, por ejemplo tenemos la siguiente disposición:

.
├── .git/
├── documentos / # Sin package.json
├── pipelines / # Sin package.json
└── proyecto / # Con package.json y .husky

Es decir, que nuestro proyecto está en un directorio llamado «proyecto», entonces la instalación la realizaremos igual que antes (claro que la ejecución la realizamos donde esté el package.json).

La inicialización en cambio es un poco diferente… más bien es algo artesanal, así que lo único que haremos es crear nosotros el script del package.json de forma que quede de la siguiente manera:

"prepare": "cd .. && husky proyecto/.husky"

al no inicializar nada, ejecutaremos directamente ese script:

npm run prepare

y en los diferentes scripts que tengamos en el directorio «.husky» escribiremos el cambio de directorio y después las acciones que deseemos (por ejemplo en script: proyecto/.husky/pre-commit):

cd proyecto
npm test

Resumen

Hasta aquí hemos visto qué es Husky, cómo instalarlo e inicializarlo. Más adelante en otros artículos iremos utilizando los diferentes commit hooks para:

  • pre-commit: Validar la escritura de código (lint), formateo (prettier) y testeo mediante Lint-Staged.
  • prepare-commit-msg: Modificar el mensaje de commit para cambiar el texto que representa un emoji por el emoji (usando devmoji).
  • commit-msg: Validar el mensaje de commit para que cumpla las reglas de Conventional Commits mediante commitlint.