Cómo facilitar el flujo de trabajo de desarrollo de su equipo con Git Hooks

Publicado: 2022-03-10
Resumen rápido ↬ Los flujos de trabajo de desarrollo pueden salirse de control fácilmente y comenzar a causar confusión y fricciones dentro de los equipos, especialmente a medida que crecen en tamaño. Ha habido demasiadas ocasiones en las que nuestra revisión de código consistía simplemente en notar la coma faltante o las pruebas fallidas que nunca se ejecutan antes de enviarlas a un repositorio remoto. Afortunadamente, existen herramientas que pueden eliminar esta fricción, hacer que los flujos de trabajo de los desarrolladores sean más sencillos y ayudarnos a concentrarnos en las cosas que realmente importan más. Gracias a git y los ganchos que proporciona, tenemos una gran variedad de automatización con la que podemos configurar nuestro flujo de trabajo de desarrollo y hacernos la vida más fácil.

Uno de los principales requisitos para trabajar en equipo o en un proyecto de código abierto es utilizar un sistema de control de versiones (VCS). Git es un sistema de control de versiones distribuido gratuito y de código abierto para realizar un seguimiento de los cambios en el código fuente durante el desarrollo del software. Fue creado por Linus Torvalds en 2005 para el desarrollo del kernel de Linux. Es fácil de aprender y ocupa poco espacio con un rendimiento ultrarrápido.

Existe una gran posibilidad de que ya haya usado Git (ya que es una de las herramientas VCS más populares y mejor adoptadas disponibles en la comunidad de desarrollo), y lo más probable es que ya tenga algún conocimiento sobre la puesta en escena y la confirmación de su código empujando y tirando. desde un repositorio remoto. Este artículo no abordará los conceptos básicos de los flujos de trabajo de git, sino que se centrará principalmente en los ganchos de git y cómo utilizarlos para lograr una mejor colaboración en su equipo. Con los equipos creciendo en tamaño, es cada vez más importante mantener a los colaboradores en línea y mantener diferentes reglas sobre el código.

¿Qué son los ganchos Git?

Los ganchos de Git son scripts que se activan cuando se realizan acciones o eventos específicos en un repositorio de Git. Estas acciones se refieren a partes del flujo de trabajo de control de versiones, como confirmar y enviar. Los ganchos pueden ser realmente útiles al automatizar tareas en su flujo de trabajo de git. Por ejemplo, pueden ayudarnos a validar la sintaxis de nuestro código base en función de algunas reglas específicas, o ejecutar algunas pruebas antes de confirmar nuestros cambios.

¡Más después del salto! Continúe leyendo a continuación ↓

¿Cómo configurarlos?

Los ganchos de Git son una función integrada, lo que significa que podemos acceder a ellos y comenzar a usarlos siempre que se inicialice un repositorio de Git. Echemos un vistazo con más detalle a lo que eso significa tratando de configurarlos.

Usando su terminal favorito, cree un nuevo repositorio de git.

 mkdir my-new-repository && cd my-new-repository git init ls -la

Notará que se acaba de crear un nuevo directorio oculto. Esta carpeta .git se usa desde git para almacenar información relacionada con el repositorio, como hashes de control de versiones, información sobre confirmaciones, direcciones de repositorios remotos, etc. Esta es también la carpeta donde realmente viven los ganchos para git .git/hooks . Puede encontrar algunos scripts de muestra precargados creados automáticamente durante la inicialización. Estos son en realidad los scripts que se activarán después de acciones específicas.

 ls .git/hooks

Algunas de las muestras que puedes encontrar son:

  • pre-commit.sample : invocado justo antes de realizar la confirmación.
  • commit-msg.sample : edite el archivo de mensajes en su lugar.
  • post-receive.sample : invocado después de que el repositorio remoto se haya actualizado.

Bajo el capó

Ahora que sabemos dónde podemos encontrar ganchos, demos un paso atrás para entender cómo funcionan realmente.

Los ganchos de Git se basan en eventos, por lo que siempre que ejecutemos un comando de git en el flujo de desarrollo, git verificará las carpetas de ganchos para encontrar si hay un script asociado para ejecutar. Algunos de estos scripts se ejecutarán antes o después de estas acciones de flujo de desarrollo.

Un buen ejemplo para que analicemos y entendamos más específicamente el flujo bajo el cual se activan los ganchos es el flujo de trabajo de confirmación, que es un caso de uso bastante familiar.

Cada vez que cometemos cambios en nuestro código base, algunos de estos ganchos relacionados se activan en el siguiente orden:

  1. pre-commit : inspecciona la instantánea que está a punto de confirmarse y verifica qué se va a confirmar.
  2. prepare-commit-msg : le permite editar el mensaje predeterminado antes de que el autor de la confirmación lo vea.
  3. commit-msg : establece el mensaje de confirmación en una plantilla.
  4. post-commit : ejecuta una acción justo después de que se haya completado la confirmación y envía una notificación, por ejemplo.
Hooks ejecutándose durante el proceso de creación de commit
Ganchos que se ejecutan durante el proceso de creación de la confirmación (Créditos de la imagen: Atlassian Bitbucket) (Vista previa grande)

En el repositorio anterior, intentemos ahora y agreguemos algunos scripts personalizados previos y posteriores a la confirmación para poder visualizar mejor cómo funcionan realmente los git hooks.

 nano .git/hooks/pre-commit

Agrega el siguiente fragmento:

 #!/bin/sh echo Changes are about to be committed

Asegúrese de que nuestros scripts sean ejecutables:

 chmod +x .git/hooks/pre-commit

Repita el proceso anterior para el script post-commit :

 nano .git/hooks/post-commit
 #!/bin/sh echo Changes have been committed
 chmod +x .git/hooks/post-commit

Ahora podemos agregar un nuevo archivo nano index.html con un pequeño fragmento de HTML solo para fines de demostración (no es necesario que los validadores de HTML sepan esto).

 <h1>Hello world from our new repository!</h1>

Agregaremos los cambios en nuestra base de código a través de la puesta en escena y luego confirmaremos esto:

 git add . git commit

Después de que la confirmación se haya procesado con éxito, podemos ver el siguiente resultado de los dos scripts agregados anteriormente:

 Changes are about to be committed Changes have been committed

Como era de esperar, git activó ganchos en el flujo de confirmación. Los scripts pre-commit y post-commit que se agregaron se están ejecutando y se ejecutarán en la secuencia correcta (según el orden que mencionamos anteriormente).

Esta fue una demostración simple para comprender cómo funcionan los scripts de flujo de trabajo de confirmación y cómo se ejecutan. Para obtener más detalles sobre este flujo de trabajo, puede leer más en la documentación.

En el ejemplo anterior, elegimos escribir estos dos scripts en bash, pero la verdad es que git admite ganchos que se pueden escribir en cualquier lenguaje de script que queramos. Ruby, Python o JavaScript son excelentes alternativas, siempre que establezcamos el shebang correcto en la primera línea de nuestro script ejecutable.

Por ejemplo, podemos reescribir el gancho pre-commit como un script de Node.js como se muestra a continuación:

 #!/usr/bin/env node console.log("Changes are about to be commited")

Ganchos locales y remotos

Los ganchos se separan entre locales y remotos (o cliente y servidor). Mientras que los enlaces locales se ejecutan antes o después de acciones específicas en el repositorio local, los enlaces remotos se ejecutan antes o después de las inserciones en el servidor. Los locales no se pueden usar para hacer cumplir las políticas, ya que su naturaleza permite que los desarrolladores los modifiquen fácilmente. Se utilizan principalmente para cumplir con algunas pautas específicas que queremos aplicar dentro de un equipo. En caso de que queramos ser más estrictos y hacer cumplir algunas políticas para nuestro repositorio, residemos en ganchos remotos.

Ganchos locales

  • pre-commit
  • prepare-commit-msg
  • commit-msg
  • post-commit
  • applypatch-msg
  • pre-applypatch
  • post-applypatch
  • pre-rebase
  • post-rewrite
  • post-checkout
  • post-merge
  • pre-push

Ganchos remotos

  • pre-receive
  • update
  • post-receive

Compartiendo ganchos

Los ganchos de Git tienen que ver con compartirlos dentro del equipo. Esta es la razón principal por la que existen: promover una mejor colaboración en equipo, automatizar procesos perjudiciales y permitirnos centrarnos solo en las partes importantes de la base de código.

Como se indicó anteriormente, .git/hooks es la carpeta que aloja nuestros ganchos personalizados, pero esto no es realmente útil cuando necesitamos compartir estos scripts dentro del equipo, ya que git no rastrea esta carpeta.

Un buen enfoque para resolver esto es agregar todos nuestros ganchos personalizados en una carpeta separada dentro de nuestro repositorio. Por ejemplo, podemos agregar una carpeta .githooks y guardar los scripts ejecutables allí. Luego, en la inicialización del proyecto, podemos copiar o vincular explícitamente estos scripts a la carpeta original para mantener nuestros ganchos .git/hooks .

 find .git/hooks -type l -exec rm {} \\; find .githooks -type f -exec ln -sf ../../{} .git/hooks/ \\;

Alternativamente, si está utilizando la última versión de git (hablando de 2.9 y superior), podemos configurar directamente la ruta de acceso de git a nuestra carpeta personalizada:

 git config core.hooksPath .githooks

Git Hooks Made Easy (un caso de uso de base de código de JavaScript)

Existen herramientas que nos ayudan a integrar aún más los git hooks a las necesidades de nuestro código base. Específicamente para las bases de código de JavaScript, existe Husky con el que podemos personalizar fácilmente las acciones en los eventos de git a través de la configuración.

Por ejemplo, podemos eliminar fácilmente nuestro código o ejecutar algunas pruebas en el evento pre-commit y proceder a la confirmación en función de si la eliminación, la prueba o ambas tienen éxito o no.

Esto se puede lograr ampliando la configuración de package.json simplemente como:

 { "scripts": { "test": "echo Running tests" }, "devDependencies": { "eslint": "5.16.0", }, "husky": { "hooks": { "pre-commit": "eslint . && npm test", } } }

Conclusión

En este artículo, descubrimos que diferentes acciones realizadas en un repositorio de git pueden activar opcionalmente la ejecución de scripts personalizados. Esos scripts pueden estar bajo el control del desarrollador localmente o administrarse de manera más central para un equipo o proyecto en forma remota. También aprendimos que las secuencias de comandos a menudo se escriben en una secuencia de comandos de shell como bash, pero en realidad pueden usar casi cualquier lenguaje de secuencias de comandos, incluso JavaScript.

Los ganchos de Git pueden ser una parte realmente poderosa de un flujo de trabajo bien diseñado, y lo animo a que los pruebe y vea qué puede hacer por sus propios proyectos.