Table des matières :
- Validator PrestaShop en ligne vs ps-validator en terminal : périmètre (et angles morts)
- Préparer un environnement reproductible : PHP/Composer vs conteneur Docker
- Implémenter
ps-validator: un wrapper terminal stable (local + CI) - CI/CD : intégrer ps-validator dans GitHub Actions et GitLab CI sans plomber les temps de build
- Rendre le signal “qualité” exploitable : tests, linters, SBOM et durcissement
- Checklist d’industrialisation : compat PS 8/9, artefacts ZIP, seuils et branches protégées
Validator PrestaShop en ligne vs ps-validator en terminal : périmètre (et angles morts)
Le Validator PrestaShop sert d’abord à une chose : vérifier qu’un module est publiable (structure, conformité minimale, packaging) et qu’il ne viole pas un certain nombre de règles connues (métadonnées, fichiers interdits, patterns risqués). Dans les faits, c’est un outil de compliance plus qu’un outil de QA. En CI/CD, l’intérêt est simple : arrêter les régressions “bêtes” (arborescence, ZIP bancal, oubli de fichiers, mauvais config.xml, etc.) avant qu’un humain (reviewer, équipe QA, ou Addons) ne perde du temps.
La différence clé entre l’outil “en ligne” et une exécution en terminal n’est pas tant ce qui est contrôlé, mais la manière dont le contrôle s’insère dans votre cycle de livraison :
| Critère | Validator en ligne | ps-validator en terminal (CI/CD) |
|---|---|---|
| Reproductibilité | Dépend du service (version, disponibilité) | Version pin + logs versionnés |
| Automatisation | Plutôt manuel | Bloquant sur MR/PR (exit code) |
| Traçabilité | Résultat souvent “jetable” | Logs attachés au pipeline + artefacts |
| “Temps perdu” | Souvent à la fin (au moment du zip / dépôt) | Très tôt (au moment du push) |
| Variantes de packaging | Souvent testé via un ZIP final | Peut tester dossier et artefact ZIP (selon version / commande) |
Dans un contexte PrestaShop “agence” (souvent multi-projets, multi-clients, et parfois multi-régions UE), ce caractère reproductible est particulièrement utile : vous standardisez un socle de conformité sans dépendre des postes, ni d’un service externe au moment critique (release, hotfix, audit).
Il faut aussi être clair sur ses limites : le Validator n’est ni un test fonctionnel, ni un scan exhaustif de sécurité, ni un oracle de compatibilité runtime. Il ne remplace pas des tests PHPUnit, un lint strict (PHPStan/Psalm), un audit de dépendances, ni des checks spécifiques aux versions (PrestaShop 8.1 vs 9.x, PHP 8.1 vs 8.3). Si votre module passe le Validator mais casse au chargement du container Symfony ou déclenche une fatale sur une boutique réelle, ce n’est pas un “bug du Validator” : c’est une couverture différente.
Quelques “angles morts” fréquents, observés en modules PrestaShop :
- Compatibilité réelle : un module peut être “conforme” mais appeler un service Symfony non disponible sur une cible (ou utiliser une classe Core déplacée/dépréciée).
- Qualité runtime : mémoire, perfs, requêtes SQL non indexées, hooks lourds en front-office… rien de tout cela n’est évalué.
- Conformité sécurité : secrets committés, dépendances vulnérables, usage de fonctions dangereuses en contexte, SSRF/IDOR, etc. Le Validator ne remplace pas une revue sécurité.
- Supply-chain : dépendances front (npm) et PHP (Composer), licences, et provenance des artefacts ne sont pas “assurées” par la validation structurelle.
- Internationalisation/UX : qualité des traductions, cohérence Back-Office, et régression UI ne sont pas dans son périmètre.
Enfin, l’exécution en terminal (ce que l’on va appeler ici ps-validator) change la donne : reproductibilité, intégration aux pipelines, et feedback immédiat sur une MR/PR. Martin Fowler résume bien l’objectif de la CI : « Continuous Integration doesn’t get rid of bugs, but it does make them dramatically easier to find and remove. » (martinfowler.com). L’idée n’est pas de “faire plus de checks”, mais d’obtenir un signal fiable et automatisé, avec un code de retour qui bloque la fusion.
Préparer un environnement reproductible : PHP/Composer vs conteneur Docker
Sur le papier, exécuter le Validator “à la main” en local semble trivial. En pratique, c’est rarement stable sur un poste dev : extensions PHP requises, version de PHP attendue par le Validator, dépendances Symfony, et variations entre OS (Linux/macOS/WSL). Pour du CI/CD et du support d’équipe, le plus important n’est pas “que ça tourne une fois”, mais que ça tourne pareil sur tous les runners.
Le conteneur est la stratégie la plus robuste : vous figez une version de PHP (ex. PHP 8.2 ou PHP 8.3), vous capturez les dépendances dans une image, et vous exécutez le check avec un volume monté sur le répertoire du module. Ça s’aligne avec un principe d’exploitation très concret (souvent oublié sur les projets PrestaShop legacy) : « Keep development, staging, and production as similar as possible. » (The Twelve-Factor App – Dev/Prod parity). Même si votre prod n’exécute pas le Validator, vos runners CI, eux, doivent rester cohérents.
Deux recommandations pratiques (souvent décisives pour éviter les “ça marche sur mon PC”) :
- Alignez la version de PHP utilisée par le Validator avec vos cibles de support. Si vous maintenez un module annoncé compatible PS 8.1 et PS 9, testez au minimum le Validator et vos linters sur un couple de versions PHP représentatives (job “matrix” en CI si nécessaire).
- Pinez la version du Validator (tag ou SHA). Le
mainest confortable, mais il peut introduire des changements de règles et donc des échecs “surprise” sur des branches stables.
Si vous avez déjà une base Docker propre pour PrestaShop, vous pouvez réutiliser la logique de build/caches décrite dans Staging PrestaShop : créer un environnement Docker fidèle à la production. Et si vous devez passer une revue de conformité sur l’exécution Docker côté CI (durcissement, UID non-root, images minimalistes), l’article CIS Benchmark Docker : exigences clés pour images conteneurisées conformes est un bon point de départ.
Enfin, pour une touche “terrain” : en environnement d’entreprise (notamment UE), on vous demandera parfois où tournent les runners (SaaS hors UE vs auto-hébergé) et comment sont gérés les secrets (tokens Git, accès registry). ps-validator en conteneur n’est pas une réponse complète à ces questions, mais c’est un composant qui se prête bien à des runners maîtrisés (réseau, images autorisées, registry interne, etc.).
Implémenter ps-validator : un wrapper terminal stable (local + CI)
Le problème à résoudre : le Validator officiel est historiquement exposé via une interface web, et sa version CLI (ou le nom exact de sa commande Symfony) peut varier selon le dépôt/tag utilisé. Pour éviter d’encoder en dur une commande fragile, on peut construire un wrapper ps-validator qui (1) build une image contenant le Validator, (2) détecte la commande disponible, (3) exécute la validation sur un chemin de module, et (4) propage un code de retour non-zéro si des erreurs sont trouvées.
Voici une approche pragmatique, testée en contexte modules PrestaShop 8.1+ / 9.x, avec des runners Linux. Elle suppose Docker disponible (local ou CI). Créez tools/ps-validator/Dockerfile :
FROM php:8.2-cli
# Dépendances minimales (à ajuster selon la version du Validator)
RUN apt-get update \
&& apt-get install -y --no-install-recommends git unzip libzip-dev \
&& docker-php-ext-install zip \
&& rm -rf /var/lib/apt/lists/*
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
WORKDIR /opt/validator
# Pin recommandé : VALIDATOR_REF=tag/commit pour reproductibilité
ARG VALIDATOR_REF=main
RUN composer install --no-interaction --prefer-dist --no-progress
COPY run.sh /usr/local/bin/run-validator
RUN chmod +x /usr/local/bin/run-validator
ENTRYPOINT ["/usr/local/bin/run-validator"]
Deux enrichissements utiles (sans sur-optimiser trop tôt) :
- Si vos builds CI sont lents, activez BuildKit (
DOCKER_BUILDKIT=1) et évitez d’invalider le cache inutilement (ne copiez pas tout le repo dans l’image ; ici on clone directement le dépôt du Validator, ce qui limite les variations). - Si vous devez durcir, vous pouvez faire évoluer l’image vers un utilisateur non-root, mais attention : certains runners Docker-in-Docker et montages de volumes peuvent introduire des frictions de permissions. Faites-le quand le besoin est réel (politique sécurité / conformité).
Puis tools/ps-validator/run.sh (détection de commande + exécution) :
#!/usr/bin/env bash
set -euo pipefail
MODULE_PATH=${1:-}
if [[ -z "$MODULE_PATH" ]]; then
echo "Usage: ps-validator <chemin-du-module>" >&2
exit 2
fi
if [[ ! -d "$MODULE_PATH" ]]; then
echo "Module path not found: $MODULE_PATH" >&2
exit 2
fi
# Détection : on cherche une commande plausible exposée par le Validator
# (les noms exacts varient selon versions ; on évite de figer un seul nom)
CANDIDATES_REGEX='(prestashop:.*valid|validator:.*module|.*:validate:module|.*:module:validate)'
CMD=$(php bin/console list --raw 2>/dev/null | awk '{print $1}' | grep -Ei "$CANDIDATES_REGEX" | head -n 1 || true)
if [[ -z "$CMD" ]]; then
echo "Impossible de détecter la commande de validation dans ce build du Validator." >&2
echo "Debug: php bin/console list" >&2
exit 3
fi
# Exécution : on passe le chemin du module. Ajoutez ici des options si votre version les supporte.
php bin/console "$CMD" "$MODULE_PATH"
Astuce “qualité de signal” : si vous voulez des logs plus faciles à lire dans GitHub/GitLab (et à garder en artefact), vous pouvez encapsuler l’exécution avec tee, sans casser le code de retour :
# Exemple d’usage dans un job CI
set -o pipefail
php bin/console "$CMD" "$MODULE_PATH" | tee validator.log
Enfin, le wrapper côté repo (ex. bin/ps-validator) :
#!/usr/bin/env bash
set -euo pipefail
MODULE_PATH=${1:-"$PWD"}
docker build -t ps-validator:local tools/ps-validator \
--build-arg VALIDATOR_REF=main >/dev/null
docker run --rm \
-v "$MODULE_PATH:/work" \
ps-validator:local /work
Ce que vous gagnez : un point d’entrée unique (bin/ps-validator), exécutable localement et réutilisable en CI, sans dépendre du poste dev.
Ce que vous perdez : un peu de temps de build si vous ne mettez pas de cache (on le traite dans la section CI/CD).
Mini-scenario concret (très fréquent) : une PR supprime “par mégarde” un fichier attendu (ou renomme un dossier), le module continue de fonctionner en environnement de dev (autoload déjà en cache, assets présents), mais le ZIP publié est incomplet. Avec ps-validator en fast-fail, vous bloquez la fusion avant que ce défaut ne se retrouve en recette ou en soumission Addons.
CI/CD : intégrer ps-validator dans GitHub Actions et GitLab CI sans plomber les temps de build
En CI/CD, le piège classique est de rebuild l’image du Validator à chaque job, sans cache Docker ni pin de version. Résultat : pipelines lents et non déterministes. La règle : pinner (VALIDATOR_REF sur un tag/commit) et cacher (layers Docker ou artefacts). Si vous avez déjà une stratégie CI/CD PrestaShop mature (build de démos, environnements éphémères), alignez ce job sur votre “standard” : PrestaShop CI/CD : générer des démos à la demande en minutes.
Exemple GitHub Actions minimal (runner Linux, Docker disponible) :
name: module-quality
on:
pull_request:
push:
branches: [ main ]
jobs:
prestashop-validator:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build ps-validator image
run: |
docker build -t ps-validator:ci tools/ps-validator \
--build-arg VALIDATOR_REF=main
- name: Run validator on module
run: |
./bin/ps-validator ./
Pour GitLab CI, même logique ; l’essentiel est d’activer le service Docker-in-Docker ou d’utiliser un runner “shell” avec Docker local. Exemple (très direct) :
stages: [ test ]
ps_validator:
stage: test
image: docker:27
services:
- docker:27-dind
variables:
DOCKER_TLS_CERTDIR: "/certs"
script:
- docker build -t ps-validator:ci tools/ps-validator --build-arg VALIDATOR_REF=main
- docker run --rm -v "$CI_PROJECT_DIR:/work" ps-validator:ci /work
Deux points pratiques pour ne pas dégrader vos pipelines :
1) Caches Docker : sur GitHub, utilisez docker/build-push-action + cache local/registry si vous voulez aller plus loin ; sur GitLab, activez le cache de layers si votre infra le permet (registry + buildkit). Dans des pipelines modules, c’est souvent ce qui fait la différence entre un job “acceptable” (20–40s) et un job “qui décourage tout le monde” (3–6 min).
2) Scopes : ne lancez le Validator que si le diff touche le module (ex. changements dans modules/monmodule/), sinon vous faites du bruit et du coût. Sur GitHub Actions, c’est typiquement un filtre sur chemins ; sur GitLab, une règle rules:changes.
Point d’attention “terrain” : Docker-in-Docker implique parfois des contraintes sécurité (mode privilégié, réseau). Si votre organisation veut limiter ces risques, vous pouvez :
- basculer sur un runner shell avec Docker local (plus simple à contrôler),
- ou construire/publier l’image du Validator une fois (registry interne), puis uniquement
docker pull+docker runsur les projets modules.
Rendre le signal “qualité” exploitable : tests, linters, SBOM et durcissement
Le Validator doit être un garde-fou, pas votre unique standard. En pratique, une pipeline modules PrestaShop solide combine :
- unit tests et/ou integration tests (PHPUnit) ;
- analyse statique (PHPStan/Psalm) ;
- formatage/lint (PHP-CS-Fixer, ESLint si assets front) ;
- contrôle dépendances (Composer audit, npm audit) ;
- et éventuellement SBOM + policy.
Une manière simple d’éviter l’“effet sapin de Noël” (trop de checks, trop de bruit) : clarifier ce que chaque étape est censée attraper.
| Couche | Objectif | Exemple d’échec détecté tôt |
|---|---|---|
ps-validator |
conformité structure/packaging | module non publiable, fichier interdit, metadata incohérentes |
| Lint/CS | stabilité et conventions | erreurs de syntaxe, style bloquant, imports incohérents |
| Analyse statique | robustesse | type mismatch, appels à méthodes inexistantes, null deref probable |
| Tests | comportement | régression fonctionnelle sur hook, service, config |
| Audit deps + SBOM | supply-chain | CVE dans une dépendance, licence non conforme, traçabilité insuffisante |
Si vous exécutez déjà des tests PHPUnit sous Docker, réutilisez la même mécanique de runner, pour éviter de multiplier les environnements. Voir l’approche concrète dans : ps_onepagecheckout : exécuter les tests PHPUnit avec Docker et PrestaShop. Le pattern efficace est : un job “fast fail” (ps-validator + lint), puis un job plus coûteux (tests) uniquement si le fast fail passe.
Sur la sécurité supply-chain, le Validator ne suffit pas. Si votre module embarque des dépendances (dossier vendor/ ou dépendances front), vous devez produire une SBOM (CycloneDX/SPDX) et vérifier des politiques (licences, CVE). L’article PrestaShop : sécuriser APIs et modules avec SBOM, WAF et CI/CD pose un cadre outillé, applicable aux modules.
Et côté hébergement/runners, si vous opérez vos propres machines (GitLab runners, Jenkins), ne zappez pas la base : patching, permissions, secrets, et séparation des environnements. Référence utile : PrestaShop auto-hébergé : prérequis d’installation, maintenance et sécurité.
Enfin, dans beaucoup d’organisations (notamment en Europe), les exigences de conformité montent sur la traçabilité (qui a produit quoi, quand, avec quelle version d’outil) : ps-validator en CI aide précisément sur ce point, car vous pouvez archiver (a) la version pin du Validator, (b) les logs, et (c) l’artefact validé.
Checklist d’industrialisation : compat PS 8/9, artefacts ZIP, seuils et branches protégées
Le cas d’échec le plus fréquent en validation module n’est pas un “vrai bug” : c’est le packaging. En CI, automatisez la génération de l’artefact ZIP (nom propre, exclusion de .git/, node_modules/, tests/ si non requis, etc.) et validez l’artefact, pas le répertoire de travail. Ça évite le syndrome “ça passe en local, ça échoue quand je zippe”. Un ZIP reproductible (mêmes fichiers, même ordre, mêmes droits) vous rend aussi plus fiable sur la supply-chain (hash stable).
Une approche simple et propre, quand votre module est son propre dépôt Git : produire un ZIP via git archive (évite d’embarquer des répertoires “hors release” par accident) :
# Exemple : créer dist/monmodule.zip à partir de HEAD
mkdir -p dist
git archive --format=zip --output "dist/monmodule.zip" HEAD
Si votre module est dans un mono-repo, vous pouvez archiver uniquement un sous-répertoire (en adaptant le chemin). L’idée reste la même : le ZIP doit refléter exactement ce que vous livrez.
Sur PrestaShop 9.x (Symfony 6.4, PHP 8.3 fréquemment), beaucoup d’échecs viennent de compatibilité implicite : namespaces, dépendances Symfony, et usage de composants dépréciés côté core. Pour cadrer ce point, gardez en tête les contraintes discutées dans :
- PrestaShop 9 : guide de migration Symfony 6.4 et PHP 8.3
- PrestaShop modules : optimiser la compatibilité Symfony 6.4 et Admin API
Enfin, pour que ps-validator serve réellement à quelque chose, il faut le brancher au contrôle d’accès : branches protégées, statuts obligatoires, et seuils. Une implémentation raisonnable :
- PR/MR bloquée si le job
ps_validatoréchoue (exit code non-zéro). - Artefact attaché (logs du Validator + ZIP généré) pour analyse sans relancer.
- Exécution uniquement sur les chemins pertinents (
modules/monmodule/**). - Version pin du Validator (tag/commit) + revue périodique (mensuelle ou trimestrielle) pour éviter les surprises.
- Même logique sur les branches de maintenance (ex.
1.7.x,8.x,9.x) : le but est de réduire les “regressions de packaging” lors de hotfix.
Ce n’est pas “du process” : c’est de la réduction de bruit. Le Validator fait tomber des erreurs triviales tôt, et votre temps de review part sur les vrais sujets (API, compat, perfs, sécurité).




