Aller au contenu

Husky : intégration continue et équipes

En CI, les hooks sont inutiles (la CI exécute elle-même les contrôles) et peuvent même gêner (modification du dépôt, installation de scripts). Trois approches :

Fenêtre de terminal
HUSKY=0 npm ci # variable d'environnement : Husky ne s'active pas
npm ci --ignore-scripts # n'exécute aucun script d'installation

Ou rendre le script prepare tolérant :

{
"scripts": {
"prepare": "husky || true"
}
}

|| true évite l’échec de npm ci quand Husky n’est pas disponible (installation de production sans dépendances de développement) :

Fenêtre de terminal
npm ci --omit=dev # Husky (devDependency) absent : prepare ne doit pas échouer

Dans un workflow Gitea Actions :

jobs:
qualite:
runs-on: ubuntu-latest
env:
HUSKY: '0'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
- run: npm ci
- run: npm run lint && npm run format:check && npm test

Voir Gitea Actions : écrire un workflow.

Les hooks locaux se contournent : la CI doit refaire les mêmes contrôles, de façon obligatoire.

Contrôle du hook Équivalent en CI
pre-commit : lint-staged npm run lint et npm run format:check sur tout le projet
commit-msg : commitlint npx commitlint --from origin/main --to HEAD
pre-push : tests npm test (avec couverture)
- run: npx commitlint --from "origin/${{ gitea.base_ref }}" --to HEAD --verbose
if: gitea.event_name == 'pull_request'

La checkout par défaut est superficielle : ajouter fetch-depth: 0 à actions/checkout pour disposer de l’historique nécessaire à commitlint --from.

Pratique Raison
Versionner .husky/ et les configurations (lint-staged, commitlint, ESLint, Prettier) Mêmes règles pour tous
Script prepare Active les hooks à l’installation, sans geste manuel
Épingler les versions (package-lock.json) Mêmes résultats d’un poste à l’autre
Documenter dans README ou CONTRIBUTING Une phrase : « les hooks s’installent avec npm install »
Garder les hooks rapides Sinon, contournement par habitude
Refaire les contrôles en CI Filet de sécurité

Extrait de CONTRIBUTING.md :

## Avant de contribuer
1. `npm install` : installe les dépendances et active les hooks Git (Husky).
2. Les commits suivent Conventional Commits (`feat(portée): description`).
3. Avant chaque commit, le code est formaté et analysé automatiquement.
4. Avant chaque envoi, les tests sont exécutés.

Quand package.json n’est pas à la racine du dépôt Git :

{
"scripts": {
"prepare": "cd .. && husky frontend/.husky"
}
}

Husky doit être exécuté depuis la racine du dépôt (là où se trouve .git) en indiquant le dossier des hooks (frontend/.husky). Les commandes du hook s’exécutent alors depuis la racine : se déplacer dans le sous-dossier si nécessaire :

frontend/.husky/pre-commit
cd frontend
npx lint-staged

Pour un monorepo géré par un espace de travail (pnpm, npm workspaces), installer Husky à la racine et configurer lint-staged par motif de chemin.

Les clients Git graphiques lancent les hooks sans charger le profil du shell : Node.js installé par nvm n’est alors pas trouvé. Créer ~/.config/husky/init.sh (exécuté avant chaque hook) :

Fenêtre de terminal
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"

Voir Node.js : gérer les versions.

  • Un hook est un script exécuté sur la machine de chaque contributeur : une modification malveillante de .husky/ s’exécuterait chez tous au prochain commit. Relire les changements de .husky/ en revue de code.
  • Ne pas mettre de secrets dans les hooks.
  • Ne pas faire d’appels réseau dans les hooks (lenteur, dépendance à la connexion).
  • Les dépôts clonés depuis une source inconnue ne devraient pas être installés sans relecture (le script prepare s’exécute à npm install).

Retour d’expérience : gérer les contournements

Section intitulée « Retour d’expérience : gérer les contournements »
Constat Réponse
--no-verify fréquent Hook trop lent ou instable : l’alléger
Hooks ignorés par une partie de l’équipe Documenter, vérifier en CI
Messages refusés pour des détails Assouplir les règles (avertissement plutôt qu’erreur), documenter la convention
Formatage qui modifie beaucoup de fichiers Formater tout le projet en un commit dédié, puis laisser lint-staged maintenir
Symptôme Piste
npm ci échoue en CI avec husky: not found HUSKY=0, --ignore-scripts, ou "prepare": "husky || true"
.git can't be found husky lancé hors de la racine du dépôt : cd .. && husky dossier/.husky
commitlint --from : fatal: bad revision fetch-depth: 0 dans actions/checkout
Les hooks ne se lancent pas chez un collègue npm install non exécuté, ou core.hooksPath modifié localement
Les hooks modifient des fichiers en CI HUSKY=0
Conflit avec un autre outil de hooks Un seul outil à la fois : vérifier git config core.hooksPath

Ubuntu 24.04 et 26.04 : différences à connaître

Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »

Aucune propre à Ubuntu. Sur les runners de CI sous Ubuntu, Node.js et Git doivent être disponibles pour npm ci (voir Gitea : Actions (CI)).