# Hooks pre-commit : lancer PHPCS et les tests avant chaque commit sans ralentir l’équipe

> Mettre en place GrumPHP ou Husky pour bloquer un commit non conforme aux standards, en ne vérifiant que les fichiers modifiés pour rester rapide.

- Auteur : Clément Hadrot
- Publié le : 2021-06-17
- Mis à jour le : 2021-06-17
- Catégorie : Tests
- URL : https://wpmoderne.dev.wordpress-developpement.fr/tests/hooks-pre-commit-phpcs-tests-grumphp-husky/

## L’essentiel

- Ne vérifier que les fichiers modifiés, jamais tout le dépôt
- GrumPHP pour un projet PHP, Husky pour un projet JS/mixte
- Toujours garder une option d'échappement documentée

Après trois commits consécutifs cassant les standards de code sur une même semaine, chacun détecté seulement au moment de la revue de pull request, l'équipe a décidé de déplacer la vérification plus tôt dans le flux : directement avant que le commit ne soit créé, sur le poste du développeur. Le piège classique de cette approche est de vouloir tout vérifier à chaque commit — tests complets compris — et de transformer un geste censé prendre deux secondes en pause café obligatoire de deux minutes.

Deux outils dominent selon la nature du projet : GrumPHP pour un projet essentiellement PHP, Husky quand le projet mélange PHP et JavaScript avec un `package.json` déjà présent. Les deux reposent sur le même mécanisme natif Git : le hook `pre-commit`.

## Installer GrumPHP sur un projet WordPress

```
composer require --dev phpro/grumphp

# grumphp.yml
grumphp:
    tasks:
        phpcs:
            standard: WordPress
        phpunit:
            config_file: phpunit.xml
```

Par défaut, GrumPHP installe automatiquement le hook Git à l'installation de Composer, sans configuration supplémentaire. Chaque `git commit` déclenche alors les tâches définies.

## Ne vérifier que les fichiers modifiés

Le piège le plus courant consiste à lancer PHPCS ou PHPUnit sur l'ensemble du dépôt à chaque commit. Sur un projet de plusieurs centaines de fichiers, cela ralentit chaque commit de plusieurs secondes, voire dizaines de secondes, ce qui pousse rapidement les développeurs à utiliser `--no-verify` pour contourner le hook. GrumPHP restreint nativement PHPCS aux fichiers modifiés via l'option `triggered_by` et l'analyse du diff Git :

```
grumphp:
    tasks:
        phpcs:
            standard: WordPress
            triggered_by: ['php']
        git_commit_message:
            max_body_width: 0
```

> L'essentiel à retenir : Ne vérifier que les fichiers modifiés, jamais tout le dépôt ; GrumPHP pour un projet PHP, Husky pour un projet JS/mixte ; Toujours garder une option d'échappement documentée

## Husky pour un projet avec du JavaScript

Sur un thème ou un bloc Gutenberg avec un `package.json`, Husky couplé à `lint-staged` offre un équivalent qui ne traite que les fichiers indexés dans le commit en cours :

```
npx husky init
echo "npx lint-staged" > .husky/pre-commit
```

```
{
  "lint-staged": {
    "*.php": ["vendor/bin/phpcs"],
    "*.{js,jsx}": ["eslint --fix"],
    "*.scss": ["stylelint --fix"]
  }
}
```

`lint-staged` ne transmet aux linters que les fichiers effectivement modifiés dans le commit, ce qui garde le hook rapide quelle que soit la taille du dépôt.

## Toujours documenter une échappatoire

Un hook trop strict qui bloque un commit d'urgence en pleine astreinte produit exactement l'effet inverse de celui recherché : les développeurs prennent l'habitude d'utiliser `git commit --no-verify` par réflexe, y compris quand ce n'est pas justifié.

> La règle adoptée sur nos projets : le hook pre-commit ne vérifie que le style et les erreurs de syntaxe évidentes, jamais la suite de tests complète. Les tests d'intégration restent réservés à la pull request et à l'intégration continue, où le temps d'exécution compte moins.

## Que garder pour le pre-commit, que garder pour la CI

- Pre-commit : PHPCS sur les fichiers modifiés, détection de secrets, validation du message de commit
- Pre-push (optionnel) : tests unitaires purs, rapides et sans base de données
- Intégration continue : suite complète de tests d'intégration, PHPStan, analyse de sécurité

## En résumé

Un hook pre-commit efficace se limite volontairement à ce qui s'exécute en quelques secondes sur les fichiers réellement modifiés. Le pipeline d'intégration continue, plus lent mais exhaustif, reste le bon endroit pour la suite de tests complète : les deux niveaux se complètent, ils ne se remplacent pas l'un l'autre.
