Votre premier pipeline ne concerne pas les outils, mais la cohérence

Imaginez ceci : votre équipe déploie manuellement depuis des mois. À chaque release, quelqu'un se connecte en SSH à un serveur, tire la dernière version du code et redémarre le service. Ça fonctionne, mais c'est stressant. Un jour, un développeur oublie d'exécuter les tests avant de déployer. Le lendemain, une autre personne déploie depuis une branche qui n'a pas été complètement fusionnée. Personne n'est sûr de ce qui a réellement tourné en production.

C'est le moment où la plupart des équipes décident qu'elles ont besoin d'un pipeline. Mais l'instinct est de d'abord chercher un outil : Jenkins, GitLab CI, GitHub Actions. L'outil n'est pas le problème. Le problème, c'est que chaque déploiement est un événement unique. Personne ne peut prédire ce qui se passera la prochaine fois.

La vraie solution n'est pas un outil. C'est un processus reproductible.

Commencez par un chemin unique

Avant de standardiser quoi que ce soit, choisissez une route que chaque changement suivra. Pas deux routes. Pas « ça dépend ». Un seul chemin du code à la production.

Pour la plupart des applications, ce chemin ressemble à ceci :

Voici une représentation visuelle de ce chemin doré :

flowchart TD A[Construire l'artefact] --> B[Exécuter les tests unitaires] B --> C[Déployer en développement] C --> D[Exécuter les tests d'intégration] D --> E[Déployer en préproduction] E --> F[Déployer en production]
  • Construire l'artefact
  • Exécuter les tests unitaires
  • Déployer dans un environnement de développement
  • Exécuter les tests d'intégration
  • Déployer en préproduction
  • Déployer en production

Votre équipe peut nommer ces étapes différemment. Ce n'est pas grave. L'essentiel est que chaque changement passe par la même séquence, dans le même ordre, à chaque fois.

Voici à quoi ressemble ce chemin doré sous forme de workflow GitHub Actions minimal :

name: Chemin Doré
on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - run: echo "Construire l'artefact"

  unit-tests:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - run: echo "Exécuter les tests unitaires"

  deploy-dev:
    needs: unit-tests
    runs-on: ubuntu-latest
    steps:
      - run: echo "Déployer en développement"

  integration-tests:
    needs: deploy-dev
    runs-on: ubuntu-latest
    steps:
      - run: echo "Exécuter les tests d'intégration"

  deploy-staging:
    needs: integration-tests
    runs-on: ubuntu-latest
    steps:
      - run: echo "Déployer en préproduction"

  deploy-production:
    needs: deploy-staging
    runs-on: ubuntu-latest
    steps:
      - run: echo "Déployer en production"

C'est votre chemin doré. Il n'a pas besoin d'être parfait. Il doit juste exister. Une fois qu'il existe, vous pouvez l'améliorer. Mais si vous n'avez pas de chemin unique, vous n'avez aucune base de référence pour progresser.

La cohérence est l'objectif, pas la vitesse

Lorsque vous mettez en place un pipeline pour la première fois, il semblera plus lent qu'un déploiement manuel. C'est normal. Le déploiement manuel est rapide parce qu'il saute des étapes. Il saute les tests. Il saute la vérification. Il saute les parties qui évitent les catastrophes.

Un pipeline n'est pas plus rapide à court terme. Il est plus prévisible. Et c'est la prévisibilité qui vous permettra d'aller vite plus tard.

Voici ce que la cohérence vous apporte :

  • Chaque changement est construit de la même manière. Fini le « ça marche sur ma machine ».
  • Chaque changement est testé de la même manière. Fini les suites de tests ignorées.
  • Chaque changement va dans les mêmes environnements. Fini le « j'ai oublié de déployer en préproduction ».

Quand le pipeline est cohérent, l'équipe arrête de deviner. Elle arrête de demander « Est-ce que quelqu'un a exécuté les tests ? ». Elle arrête de vérifier Slack pour les instructions de déploiement. Le pipeline répond automatiquement à ces questions.

Ajoutez des portes de risque, pas des ralentisseurs

Un pipeline cohérent, c'est bien. Un pipeline qui sait quand s'arrêter, c'est mieux.

Une porte de risque est un point du pipeline où il peut marquer une pause ou s'arrêter en fonction d'une condition. Le but n'est pas de ralentir les choses. Le but est d'attraper les problèmes avant qu'ils n'atteignent les utilisateurs.

Commencez par la porte la plus simple : les tests automatisés. Si les tests unitaires échouent, le pipeline s'arrête. Si les tests d'intégration échouent, le pipeline s'arrête. Cette porte ne nécessite aucune décision humaine. Vous écrivez les tests, et le pipeline les applique.

La deuxième porte est l'approbation manuelle pour la production. Les changements peuvent circuler automatiquement jusqu'au développement et à la préproduction. Mais pour atteindre la production, quelqu'un doit approuver explicitement. C'est utile lorsque vos tests automatisés ne sont pas encore assez complets, ou lorsqu'un changement en production a un fort impact utilisateur. Choisissez soigneusement qui peut approuver. Cela doit être quelqu'un qui comprend l'application et le risque, pas n'importe qui ayant accès.

La troisième porte est l'analyse de sécurité de base. Scannez les dépendances pour les vulnérabilités connues. Scannez le code pour les motifs dangereux. Cela n'a pas besoin d'être parfait. Commencez par les problèmes les plus courants. Ajoutez plus de vérifications au fil du temps.

Les portes de risque ne sont pas des murs

Une erreur courante est de traiter les portes de risque comme des barrières permanentes. Si une porte arrête constamment le pipeline pour des raisons triviales, l'équipe commencera à la contourner. Si une porte est toujours ignorée, elle devient du bruit.

Les portes de risque doivent être évaluées régulièrement. Posez ces questions :

  • Cette porte attrape-t-elle de vrais problèmes ?
  • Arrête-t-elle le pipeline pour de fausses alarmes ?
  • L'équipe lui fait-elle confiance ?

Si une porte n'est pas utile, supprimez-la ou ajustez-la. Une porte que personne ne respecte est pire que pas de porte du tout. Au moins sans porte, l'équipe sait qu'elle n'a pas de filet de sécurité.

Quand un chemin fonctionne, étendez-le

Une fois que votre chemin doré est stable et que vos portes de risque fonctionnent, vous remarquerez un schéma. Les mêmes étapes qui fonctionnent pour une application peuvent fonctionner pour une autre avec des ajustements mineurs. Les mêmes portes qui attrapent des problèmes dans un service peuvent en attraper dans un autre.

C'est le moment de standardiser davantage. Pas en forçant chaque équipe à utiliser le même outil, mais en fournissant un modèle de pipeline partagé. Les équipes peuvent réutiliser la même étape de construction, le même exécuteur de tests, le même script de déploiement. Elles ne personnalisent que ce qui est unique à leur application.

À partir de là, vous pouvez étendre le même schéma aux changements de base de données et d'infrastructure. Mais c'est un sujet pour un autre article.

Checklist pratique pour votre premier pipeline standardisé

  • Définissez un chemin doré du code à la production
  • Faites passer chaque changement par les mêmes étapes dans le même ordre
  • Ajoutez des portes de tests automatisés (unitaires, intégration)
  • Ajoutez une approbation manuelle pour la production si nécessaire
  • Ajoutez une analyse de sécurité de base
  • Révisez les portes après un mois. Supprimez ou ajustez ce qui ne fonctionne pas

L'essentiel à retenir

Votre premier pipeline ne consiste pas à choisir le bon outil. Il s'agit de rendre chaque déploiement prévisible. Commencez par un chemin. Rendez-le cohérent. Ajoutez des portes qui attrapent de vrais problèmes. Puis étendez le schéma au reste de vos systèmes. L'outil suivra. Le processus passe en premier.