Husky : pre-push et tests
Le hook pre-push s’exécute avant l’envoi vers le dépôt distant. Il accepte des vérifications plus longues que pre-commit (tests, types, construction), puisqu’on pousse moins souvent qu’on committe.
Répartition des contrôles
Section intitulée « Répartition des contrôles »| Hook | Durée visée | Contrôles |
|---|---|---|
pre-commit |
Quelques secondes | Formatage et analyse des fichiers indexés (lint-staged) |
commit-msg |
Instantané | Format du message (commitlint) |
pre-push |
Jusqu’à une minute | Tests, types, construction |
| Intégration continue | Plusieurs minutes | Tout, sur une machine propre |
L’intégration continue reste la référence : un hook local peut être contourné (--no-verify) ; la CI non.
Un pre-push simple
Section intitulée « Un pre-push simple ».husky/pre-push :
npm run lintnpm testSi une commande échoue, le push est refusé.
Tester seulement ce qui est concerné
Section intitulée « Tester seulement ce qui est concerné »Pour garder le hook rapide sur un gros projet :
npx vitest run --changed origin/main--changed origin/main exécute les tests des fichiers modifiés par rapport à la branche principale (Vitest : configuration et intégration continue). Avec le lanceur natif de Node.js, utiliser un script qui cible les dossiers touchés (Tests natifs de Node.js : organisation).
Vérifier les types et la construction
Section intitulée « Vérifier les types et la construction »npx tsc --noEmitnpm run buildSelon le projet : npx astro check (Astro), next build (Next.js)… Garder ici ce qui détecte les erreurs que pre-commit ne voit pas (erreurs de types entre fichiers, échec de construction).
Lire les informations fournies par Git
Section intitulée « Lire les informations fournies par Git »Git donne au hook le nom et l’adresse du dépôt distant en paramètres, et les références poussées sur l’entrée standard :
#!/usr/bin/env shdistant="$1"adresse="$2"
while read -r ref_locale sha_local ref_distante sha_distant; do echo "Envoi de $ref_locale vers $distant ($ref_distante)"doneOn peut ainsi appliquer des règles selon la branche.
Protéger la branche principale
Section intitulée « Protéger la branche principale »Empêcher de pousser directement sur main depuis un poste :
branche=$(git rev-parse --abbrev-ref HEAD)if [ "$branche" = "main" ] || [ "$branche" = "master" ]; then echo "Poussée directe sur $branche refusée : passer par une branche et une demande de fusion." exit 1fiC’est un garde-fou de confort : la vraie protection se règle sur le serveur Git (branches protégées de Gitea : Paramètres du dépôt > Branches). Voir Gitea : dépôts, accès et API.
Détecter des secrets avant l’envoi
Section intitulée « Détecter des secrets avant l’envoi »if git diff --cached --name-only origin/main..HEAD 2>/dev/null | grep -E '(^|/)\.env($|\.)' | grep -v '\.env\.example'; then echo "Un fichier .env est sur le point d'être poussé." exit 1fiUn contrôle plus complet s’appuie sur un outil dédié (par exemple gitleaks) : voir Alternative : hooks Git natifs.
Variables d’environnement dans les hooks
Section intitulée « Variables d’environnement dans les hooks »Les hooks s’exécutent avec l’environnement de la session qui lance Git. Dans un outil graphique (éditeur, client Git), le PATH peut ne pas contenir Node.js installé avec nvm : voir Dépannage pour charger nvm dans les hooks.
# ~/.config/husky/init.sh (exécuté avant chaque hook)export NVM_DIR="$HOME/.nvm"[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"Contourner
Section intitulée « Contourner »git push --no-verifyHUSKY=0 git pushContourner le pre-push doit rester exceptionnel (panne d’un outil, dépôt de secours). Si on le fait souvent, c’est que le hook est trop lent ou trop fragile : l’alléger plutôt que le contourner.
Dépannage
Section intitulée « Dépannage »| Symptôme | Piste |
|---|---|
| Le push est très long | Tests complets dans le hook : --changed, ou déplacer en intégration continue |
pre-push échoue seulement dans l’éditeur |
PATH sans Node.js : ~/.config/husky/init.sh |
| Le hook ne se lance pas | .husky/pre-push absent ou non exécutable, core.hooksPath incorrect |
origin/main introuvable |
Dépôt sans la référence : git fetch origin main |
| Impossible de pousser une branche de secours | --no-verify assumé pour ce cas |
| Les tests passent en local mais pas en CI | Voir Vitest : dépannage (fuseau horaire, variables, casse des fichiers) |
Ubuntu 24.04 et 26.04 : différences à connaître
Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »Les hooks s’exécutent avec sh, qui est dash sur Ubuntu : éviter les syntaxes propres à bash ([[ ]], tableaux) ou ajouter #!/usr/bin/env bash en première ligne du hook.