Image de couverture : Détectez les migrations Doctrine dangereuses avant qu'elles n'atteignent la production
PHP & Frameworks

Détectez les migrations Doctrine dangereuses avant qu'elles n'atteignent la production

30 août 2026
5 min de lecture
4 vues
Sébastien Muler

Une migration valide n'est pas forcément une migration sûre

Une modification de base de données peut sembler anodine lors d'une revue de code : quelques lignes SQL, des tests qui passent au vert, un déploiement qui s'annonce sans encombre. Pourtant, certaines opérations méritent une attention particulière avant d'atterrir en production. Supprimer une colonne, vider une table, ajouter une colonne NOT NULL sans valeur par défaut : autant de migrations parfaitement valides en PHP qui peuvent provoquer des pertes de données ou des temps d'arrêt.

Doctrine Migrations fait son travail : il structure les changements de schéma de façon reproductible. Mais il ne cherche pas à évaluer si une migration est risquée. Et les outils d'analyse statique habituels comme PHPStan s'intéressent à la syntaxe PHP, pas à la sémantique du SQL glissé dans addSql(). Le résultat : une faille dans la chaîne de contrôle qualité, précisément là où les conséquences sont les plus difficiles à corriger.

Les opérations SQL qui méritent une pause

Tous les projets ne sont pas exposés aux mêmes risques, mais certaines instructions SQL reviennent régulièrement dans les incidents de production liés aux migrations :

  • DROP COLUMN et DROP TABLE : une donnée supprimée en production est rarement récupérable simplement.
  • DELETE FROM sans clause WHERE : vider une table entière est irréversible sans sauvegarde récente.
  • ALTER TABLE ... ADD ... NOT NULL sans valeur par défaut : sur une table déjà peuplée, PostgreSQL refuse l'opération ou bloque la table selon les versions.
  • TRUNCATE : identique à un DELETE massif, souvent plus rapide et tout aussi définitif.
  • ALTER TABLE ... RENAME COLUMN : peut casser une application qui tourne pendant le déploiement si les deux versions du code coexistent.

Ces opérations ne sont pas interdites. Certaines sont tout à fait légitimes. Mais elles méritent une validation explicite avant le déploiement, et non une découverte en urgence après.

Intégrer une analyse statique des migrations dans la CI

L'approche décrite dans l'article original de Alkin Veysal consiste à analyser automatiquement les fichiers de migration pour y détecter des mots-clés SQL à risque. Le principe est simple : parcourir les fichiers de migration générés, extraire le contenu des appels à addSql(), et signaler toute occurrence d'une instruction sensible.

Cette vérification peut s'implémenter sous différentes formes selon le niveau de sophistication souhaité :

Un script bash minimaliste

Pour un projet avec des contraintes légères, un script grep sur les fichiers de migration suffit à démarrer :

grep -rn -E '(DROP\s+(COLUMN|TABLE)|TRUNCATE|DELETE\s+FROM|NOT NULL)' migrations/

S'il trouve des correspondances, le script retourne un code d'erreur non nul, et la CI s'arrête. Simple, sans dépendance.

Un script PHP dédié

Pour aller plus loin, un script PHP peut charger dynamiquement chaque classe de migration, instancier un objet Schema fictif, intercepter les appels à addSql() grâce à une sous-classe ou un proxy, et analyser les chaînes SQL collectées avec des expressions régulières. Cette approche permet de distinguer les faux positifs (un commentaire contenant DROP par exemple) et d'adapter la liste des patterns selon le contexte du projet.

Intégration dans GitHub Actions ou GitLab CI

Une fois le script prêt, l'intégrer dans le pipeline de CI/CD est direct. Il suffit d'ajouter une étape avant le déploiement :

- name: Analyse des migrations Doctrine
  run: php bin/check-migrations.php

En cas de détection, le job échoue avec un message explicite listant les migrations concernées et les instructions problématiques. L'équipe peut alors décider en connaissance de cause : soit ajuster la migration, soit la valider manuellement avec une note dans le code.

Adapter la liste des patterns à son projet

Aucune liste universelle ne convient à tous les projets. Un DROP COLUMN sur une table de logs temporaires n'a pas le même impact qu'un DROP COLUMN sur une table de commandes. Quelques pistes pour calibrer l'analyse :

  • Commencer par les patterns les plus évidents (DROP TABLE, TRUNCATE, DELETE FROM sans WHERE) et affiner au fil des faux positifs.
  • Distinguer les migrations de schéma pur (sans risque de perte de données) des migrations de données (risque élevé).
  • Ajouter un mécanisme d'exception explicite : un commentaire structuré dans la migration (-- mulertech:skip-check) pour signaler qu'une opération risquée a été revue et approuvée.
  • Documenter les règles dans le README du projet pour que les nouveaux contributeurs comprennent le système.

La valeur de cette analyse n'est pas de bloquer automatiquement toute modification sensible, mais de créer une friction utile : forcer une décision consciente là où l'habitude conduirait à un déploiement sans examen approfondi.

Conclusion

La CI/CD a considérablement réduit le coût des déploiements fréquents. Mais cette fluidité crée parfois une fausse impression de sécurité : si les tests passent, tout va bien. Les migrations de base de données échappent souvent à cette logique parce qu'elles opèrent à un niveau que les tests unitaires et l'analyse statique classique n'atteignent pas.

Mettre en place une analyse ciblée des fichiers de migration, même rudimentaire, comble ce manque sans alourdir significativement le pipeline. C'est une mesure de protection proportionnée au risque réel : une migration mal anticipée peut coûter bien plus qu'une heure d'intégration continue.

Partager cet article

Et votre site, il vaut quoi ?

Vitesse, accessibilité, référencement technique. Le rapport est écrit pour un dirigeant, pas pour un développeur. Gratuit, sans inscription.

Tester mon site