Les hooks Git et comment automatiser son workflow

Partager cet article :

Principe de base

Git via les « hooks » propose un moyen d’exécuter des actions personnalisées suite à des événements. Il existe différents hooks, chacun lancés à des moments différents, on peut noter par exemple les suivants :

  • pre-commit : lancé avant de lancer un commit, il peut servir par exemple de scanner son code afin de vérifier que l'on a pas oublié d'appels à des fonctions de debug (console.log en js, var_dump en php…)
  • pre-push : lancé cette fois avant un git push, je m'en sert comme rempart quand je pousse sur la branche master, afin de demander une confirmation avant de pousser effectivement les modifications.
  • Post-receive : lancé après avoir reçu des modifications, c'est à mon sens le plus utile. Il permet d'effectuer des opérations de maintenance (vidage de cache, update de base de données…) mais aussi et surtout on peut s'en servir afin de déployer du code depuis le dépôt git vers le serveur.

Il existe des hooks côté client, comme les deux premiers (pre-commit et pre-push) et des hooks côté serveur, comme le dernier (post-receive)

Les Hooks sont situés dans le dossier caché .git de votre copie de dépôt au sein du dossier hooks :

git-default-hooks.png

Ici ce sont des fichiers d'exemple, d'où le prefix .sample, afin d'utiliser un hook vous pouvez renommer celui qui vous intéresse en supprimant le .sample.

Ensuite, c'est simplement un fichier executé, donc il peut être en n'importe quel langage : ruby, bash… tant que l'entête du fichier est présent.

Exemple hook pre-commit : https://github.com/niden/Git-Pre-Commit-Hook-for-certain-words/blob/master/pre-commit

Les hooks avec gitlab

Les hooks peuvent aussi être directement sur votre serveur git, dans le cas du hook post-receive par exemple.

Attention, avec gitlab vos hooks personnalisés devront se situer dans le dossier custom_hooks, ne modifiez surtout pas ceux qui sont dans le dossier hooks car ils sont utilisés par gitlab directement. Il se peut que le dossier custom_hooks n'existe pas, dans ce cas la vous devrez le créer.

Attention encore, pensez bien à définir le propriétaire du dossier et du/des fichiers comme étant votre utilisateur (au sens unix du terme) utilisé par gitlab (par défaut : git)

Le mieux est encore d’exécuter les commande avec sudo en se "faisant passer pour lui" :

sudo -u git -H mkdir custom_hooks

sudo -u git -H vim post-receive

N'oubliez pas que les fichiers doivent être exécutables :

chmod +x post-receive

Pour en savoir plus sur les hooks je vous recommande la page dédié sur la documentation  : https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks.

À noter, je prépare un article présentant plus en détails le hook post-receive et comment je m'en sers pour déployer en prod et en préproduction suivant la branche courante, à venir dans les jours qui suivent.
 

 

Commentaires

Pour ma part, le hook pre-receive (pre-push côté serveur) me servait à faire respecter nos guidelines git. Le hook fait plusieurs checks sur chaque commit pushé, et s'il y a une erreur, il renvoit une erreur (avec la cause du refus) et le push n'est pas accepté.
Je suis passé pour un nazi au début, mais ça a sauvé la vie du repo certaines fois (merges dans le mauvais ou sur la mauvaise branche, branche partie du mauvais endroit, message de commit foireux, CRLF au lieu de LF, ...).

Si tu as un gitlab, regarde du côté de gitlab-ci (qui est intégré à gitlab) pour tes déploiements, je l'ai découvert l'année passée, ça m'a évité d'installer un Jenkins, il est simple, et il fait bien son job.

Merci pour ce retour !

Intéressant ton usage, comment vérifiais-tu que l'on pushais dans la bonne branche ?

Effectivement, j'ai configuré gitlab avec Gitlab CI, maintenant plus qu'à jouer un peu avec, si tu as des bonnes ressources sur le sujet, je suis prenneur aussi.

Salut,

Est ce que l'article sur le deploiement avec les hooks est dispo ? je ne le trouve pas.

Merci !

Salut, non je ne l'ai jamais terminé, et je me suis mis au déploiement via gitlab-ci (je vais essayer de finir un post cette fois)

Tu peux voir un exemple de post_receive que j'utilisais pour des Drupal 8 : https://gist.github.com/kgaut/cf390946dc31fb9d4e38

(et désolé pour le retard)

Ajouter un commentaire