Miroir CI des hooks pre-commit
Le problème que ce module résout
Le niveau Intermédiaire vous a fait écrire un .pre-commit-config.yaml multi-hooks qui bloque un commit localement quand une règle est violée. Mais "localement" est le mot qui pose problème : pre-commit s'installe comme un hook Git (pre-commit install), donc si un contributeur ne l'a jamais installé sur sa machine, ou le contourne avec git commit --no-verify, rien ne l'empêche de pousser du code qui viole vos règles.
La seule protection fiable, c'est de faire tourner les mêmes hooks dans un environnement que personne ne contrôle individuellement : la CI. Ce module ne construit rien de nouveau conceptuellement — c'est le prérequis "Intermédiaire module 03" qui compte, pas les modules sur les devcontainers. La CI tourne sur son propre runner, indépendamment de tout devcontainer local.
Reprendre votre config existante
Vous devriez déjà avoir, depuis le niveau Intermédiaire, un fichier .pre-commit-config.yaml avec plusieurs hooks. L'exemple ci-dessous est simplifié pour rester lisible dans ce module — votre fichier réel peut avoir des rev différents, ou un dépôt de hooks en plus (flake8, par exemple). Ce n'est pas un problème : remplacez le contenu ci-dessous par votre fichier réel avant de continuer, le raisonnement s'applique à l'identique.
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- repo: https://github.com/psf/black
rev: 24.4.2
hooks:
- id: black
Ce fichier ne change pas pour ce module — c'est justement le point. Le miroir CI ne réécrit pas vos règles, il les fait tourner ailleurs.
Le workflow GitHub Actions
Créez .github/workflows/pre-commit.yml :
name: pre-commit
on:
pull_request:
push:
branches: [main]
jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- uses: pre-commit/action@v3.0.1
Trois steps, dans cet ordre précis :
actions/checkout: sans ça, le runner n'a pas votre code source, donc rien à vérifier.actions/setup-python:pre-commitest lui-même un outil Python — l'action a besoin d'un interpréteur Python disponible pour l'installer et l'exécuter.pre-commit/action: lit votre.pre-commit-config.yamlexistant, installe les hooks qui y sont déclarés, et exécute l'équivalent depre-commit run --all-files— tous les hooks, sur tous les fichiers du repo, pas seulement les fichiers modifiés dans la pull request.
Pour exécuter un sous-ensemble de hooks ou passer des arguments supplémentaires, l'action accepte extra_args :
- uses: pre-commit/action@v3.0.1
with:
extra_args: black --all-files
Mais pour un vrai miroir — l'objectif de ce module — vous voulez l'exécution par défaut, sans extra_args, pour faire tourner exactement les mêmes hooks que ceux qui s'exécutent localement à chaque commit.
Note sur la maintenance : le dépôt officiel pre-commit/action est documenté comme étant en mode maintenance uniquement — la doc recommande pre-commit.ci pour un usage à plus long terme, qui offre plus de fonctionnalités (auto-fix, mise à jour automatique des révisions). Pour ce module, pre-commit/action reste la façon la plus directe de comprendre le mécanisme de miroir — vous pourrez migrer vers pre-commit.ci plus tard sans changer votre .pre-commit-config.yaml.
Preuve de réussite : pousser une violation, la voir échouer au même endroit
La preuve mécanique que votre miroir fonctionne n'est pas "le workflow existe" — c'est "un push qui viole une règle échoue en CI sur exactement le même hook qu'en local".
1. Reproduisez le blocage local.
echo "x=1 " >> some_file.py # espace en fin de ligne, viole trailing-whitespace
git add some_file.py
git commit -m "test: trigger trailing-whitespace"
Si pre-commit install est actif sur votre poste, ce commit est bloqué localement, avec un message du type :
trailing-whitespace...............................................Failed
- hook id: trailing-whitespace
- exit code: 1
- files were modified by this hook
2. Contournez le hook local pour pousser quand même (simulez un contributeur sans pre-commit install, ou volontairement en désaccord) :
git commit --no-verify -m "test: trigger trailing-whitespace"
git push origin votre-branche
3. Ouvrez la pull request et observez le workflow pre-commit dans l'onglet Actions de GitHub.
Le critère de réussite : le job échoue, et le log du job montre le même hook (trailing-whitespace) et la même raison d'échec que celle vue localement à l'étape 1 — pas un hook différent, pas une erreur d'infrastructure (Python manquant, pre-commit non trouvé). Si le job échoue pour une raison qui n'a rien à voir avec vos hooks (par exemple actions/setup-python absent), corrigez le workflow, ce n'est pas votre miroir qui a un problème mais son installation.
4. Corrigez la violation (retirez l'espace en fin de ligne, ou laissez le hook end-of-file-fixer/black la corriger automatiquement en local), commitez, repoussez — le job doit repasser au vert. C'est la boucle complète : bloqué en local, bloqué en CI de la même façon, débloqué de la même façon.
Ce qui vous attend au module suivant
Votre .pre-commit-config.yaml référence des dépôts externes par leur rev — un tag Git comme v4.6.0. Le module suivant vous fait auditer ce que ce tag garantit réellement, et ce qu'il ne garantit pas, en croisant cette config avec les références d'images du module 01.
Vérifiez votre compréhension
Que doit contenir, au minimum, un job GitHub Actions qui utilise pre-commit/action pour faire tourner vos hooks ?
Sans arguments supplémentaires, quels hooks pre-commit/action exécute-t-il, et sur quels fichiers ?
Vous poussez un commit avec une ligne trop longue, bloqué localement par le hook line-length de votre .pre-commit-config.yaml. Le job CI qui mirrore ce hook doit :
Envie d'être prévenu des prochains modules ?
L'Académie reste gratuite et en accès libre, sans inscription. Si vous voulez juste être averti par email à la sortie d'un nouveau module, c'est ici — aucune obligation, désinscription en un clic.