Ce que votre pipeline devrait vérifier avant le déploiement
Imaginez ceci : vous poussez une modification, le pipeline passe au vert, et vous déployez. Dix minutes plus tard, les utilisateurs signalent des erreurs. La migration de base de données a cassé une requête. Une dépendance a introduit une vulnérabilité connue. Un fichier de configuration manquait un champ obligatoire.
Le pipeline disait que tout allait bien. Mais ce n'était pas le cas.
Cela arrive quand un pipeline vérifie seulement si le code compile et si les tests passent. Ce sont des conditions nécessaires, mais pas suffisantes. Un pipeline utile agit comme un gardien : il bloque les modifications qui causeraient des problèmes en production, avant qu'elles n'y arrivent. La question est : que doit-il vérifier ?
Le build doit d'abord réussir
La barrière la plus élémentaire est de savoir si le code compile réellement. Quand un développeur pousse des modifications, le pipeline tente de compiler le code ou de produire un artefact exécutable. Si le build échoue — erreur de syntaxe, dépendance incompatible, configuration cassée — il est inutile de continuer. Le code ne peut tout simplement pas s'exécuter.
Cette barrière doit toujours être la première étape. Elle est rapide, peu coûteuse, et filtre les modifications qui ne sont même pas prêtes à être testées. Si le build échoue, le pipeline s'arrête. Le développeur reçoit un retour immédiat et peut corriger le problème avant que quiconque ne soit affecté.
Les tests unitaires vérifient le comportement, pas l'implémentation
Une fois le build réussi, la barrière suivante est celle des tests unitaires. Mais tous les tests unitaires ne se valent pas. Un bon test unitaire vérifie un comportement significatif à partir d'un point d'entrée pertinent. Pour un service backend, cela peut être un point d'API ou un cas d'usage qui traverse les couches internes réelles. Pour une application frontend, cela peut être une interaction utilisateur comme cliquer sur un bouton ou soumettre un formulaire.
L'essentiel est que les tests unitaires ne doivent pas casser quand vous refactorez du code interne. Ils ne doivent casser que lorsque le comportement observable change. Si un test unitaire échoue, cela signifie que le système ne répond plus correctement à une entrée valide. Cela vaut la peine d'arrêter le pipeline.
Certaines équipes écrivent des tests unitaires fortement couplés aux détails d'implémentation : tester des méthodes privées, tester chaque classe séparément, simuler les couches internes, et casser à chaque refactor. Ces tests créent du bruit et ralentissent la livraison. Simulez les voisins externes quand c'est nécessaire, mais laissez le comportement interne s'exécuter via le chemin que l'application utilise réellement. La barrière n'est utile que si les tests sont fiables. Si vos tests unitaires échouent fréquemment pour des raisons non fonctionnelles, les développeurs commenceront à les ignorer, et la barrière perd sa valeur.
Les tests d'intégration détectent les problèmes de connexion
Les tests unitaires peuvent s'exécuter sans dépendances externes. Les tests d'intégration, non. Ils vérifient que votre système peut réellement communiquer avec le monde extérieur : une vraie base de données, une file de messages, une API tierce.
Par exemple, votre test unitaire peut simuler la base de données et passer. Mais la vraie base de données pourrait rejeter une requête à cause d'une incompatibilité de schéma, d'un index manquant ou d'une erreur de conversion de type. Les tests d'intégration détectent ces problèmes.
Ces tests nécessitent un environnement plus complet — une base de données de test, des conteneurs ou des services en cours d'exécution. Ils sont plus lents que les tests unitaires, mais ils détectent une catégorie différente de problèmes. Si un test d'intégration échoue, cela signifie généralement que la modification ne fonctionne pas avec l'infrastructure réelle sur laquelle elle s'exécutera.
Les scans de sécurité doivent s'exécuter automatiquement
La sécurité n'est pas quelque chose que vous pouvez laisser à une revue manuelle avant la mise en production. Au moment où quelqu'un examine le code, une dépendance vulnérable pourrait déjà être en production. Les scans de sécurité automatisés peuvent s'exécuter sans intervention humaine et vérifier plusieurs choses :
- Y a-t-il des dépendances avec des vulnérabilités connues ?
- Le code contient-il accidentellement des identifiants ou des clés API ?
- Y a-t-il des motifs qui pourraient être exploités, comme une injection SQL ou une désérialisation non sécurisée ?
Certaines équipes exécutent une analyse statique sur le code source. D'autres exécutent des scans dynamiques contre une application en cours d'exécution. Les deux approches détectent des problèmes différents. L'important est que le pipeline vérifie la sécurité automatiquement, à chaque fois.
Si un scan de sécurité échoue, le pipeline s'arrête. Le développeur reçoit un rapport montrant exactement ce qui ne va pas. Pas d'approbation manuelle nécessaire, pas d'attente qu'une équipe de sécurité examine le code. La barrière elle-même bloque la modification.
La conformité aux politiques assure la cohérence
Toutes les vérifications ne doivent pas être techniques. Certaines concernent le processus et la cohérence. Les barrières de conformité aux politiques vérifient si la modification suit les règles que votre équipe ou organisation a convenues.
Les vérifications de politique courantes incluent :
- Le code a-t-il passé une revue de code ?
- Le nom de la branche suit-il la convention (par exemple,
feature/oufix/) ? - La pull request est-elle trop volumineuse ? Certaines équipes limitent les modifications à un certain nombre de lignes ou de fichiers.
- Toutes les dépendances proviennent-elles d'un registre approuvé ?
Ces vérifications sont administratives, mais elles comptent. Elles évitent les situations où quelqu'un fusionne une modification de 2000 lignes sans revue, ou où une dépendance provenant d'une source non fiable est intégrée. Le pipeline applique les règles automatiquement, afin que personne n'ait à les mémoriser.
Quand l'automatisation ne suffit pas
Les cinq barrières ci-dessus — build, tests unitaires, tests d'intégration, scan de sécurité, conformité aux politiques — peuvent toutes s'exécuter automatiquement. Le pipeline décide si c'est un succès ou un échec, et s'arrête si quelque chose ne va pas. Aucun humain n'a besoin de prendre une décision.
Mais toutes les vérifications ne doivent pas être automatisées. Certaines décisions nécessitent un jugement humain. Par exemple, une modification qui affecte un flux métier critique, ou un déploiement qui touche plusieurs services à la fois, peut nécessiter qu'une personne examine le risque et décide de poursuivre ou non. C'est là qu'intervient l'approbation manuelle.
L'essentiel est d'automatiser ce qui peut être mesuré objectivement, et de laisser les décisions subjectives aux personnes. Si une vérification peut être exprimée comme une règle qui s'applique toujours, automatisez-la. Si elle nécessite du contexte, de l'expérience ou des compromis, gardez-la manuelle.
Liste de contrôle pratique pour vos barrières de pipeline
Si vous mettez en place ou révisez vos barrières de pipeline, voici une courte liste de contrôle à considérer :
Le diagramme suivant montre comment ces barrières fonctionnent ensemble en séquence :
- Barrière de build : Le pipeline s'arrête-t-il si le code ne compile pas ou ne produit pas d'artefact ?
- Barrière de tests unitaires : Les tests vérifient-ils un comportement significatif à partir de points d'entrée pertinents, et non l'implémentation interne ?
- Barrière de tests d'intégration : Le pipeline teste-t-il contre des dépendances réelles (base de données, file d'attente, service externe) ?
- Barrière de scan de sécurité : Les dépendances sont-elles scannées pour les vulnérabilités ? Le code est-il vérifié pour les secrets et les motifs risqués ?
- Barrière de conformité : Les règles comme la revue de code, le nommage des branches et les sources de dépendances sont-elles appliquées automatiquement ?
Toutes les équipes n'ont pas besoin des cinq dès le premier jour. Commencez par le build et les tests unitaires. Ajoutez les tests d'intégration quand vous avez des dépendances externes. Ajoutez les scans de sécurité quand vous commencez à vous soucier des vulnérabilités. Ajoutez les vérifications de conformité quand vous avez besoin de cohérence dans l'équipe.
Le but d'une barrière est d'arrêter les problèmes, pas de vous ralentir
Une barrière bien conçue n'ajoute pas de friction sans raison. Elle détecte les problèmes tôt, quand ils sont peu coûteux à corriger. Un build échoué détecté dans le pipeline coûte quelques minutes. Un déploiement échoué détecté en production coûte des heures, parfois des jours.
Le but n'est pas de rendre le pipeline plus difficile à passer. Le but est de s'assurer que quand le pipeline passe, vous pouvez déployer en toute confiance. Si votre pipeline est vert mais que la production casse quand même, vos barrières vérifient les mauvaises choses. Corrigez d'abord les barrières, puis corrigez le pipeline.