De l'idée au code : la première étape de la livraison logicielle

Chaque fonctionnalité commence de la même manière : quelqu'un a une idée, l'équipe convient qu'elle vaut la peine d'être construite, et un développeur ouvre son éditeur pour écrire du code. À ce stade, le code n'existe que sur le portable d'une seule personne. Il s'exécute dans un environnement que cette personne contrôle entièrement.

Le développeur tape, teste, ajuste et observe le résultat sur son propre écran. Tout fonctionne. Le bouton apparaît là où il doit. Les données se chargent correctement. La fonctionnalité fait ce qu'elle est censée faire.

Cela ressemble à une progression. Et ça l'est. Mais le code qui tourne sur un portable n'est pas encore prêt à être livré.

Le piège de l'environnement local

Lorsque le code ne vit que sur la machine d'un développeur, il s'exécute dans une bulle. Les bibliothèques installées, la version du système d'exploitation, la configuration de la base de données, même les numéros de port — tout cela est spécifique à ce seul portable. Un autre développeur de la même équipe pourrait avoir Python 3.11 quand vous avez 3.10. Il pourrait utiliser PostgreSQL 15 pendant que vous utilisez 14. Sa version de Node pourrait être différente. Ses chemins de fichiers sont certainement différents.

Ces différences sont invisibles pendant le développement local. Le code fonctionne sur votre machine, donc vous supposez qu'il fonctionne partout. Mais dès que quelqu'un d'autre essaie de l'exécuter, des problèmes surgissent. Une bibliothèque n'est pas installée. Une configuration pointe vers un chemin local qui n'existe pas sur une autre machine. Une incompatibilité de version de dépendance provoque une erreur cryptique.

C'est le premier vrai problème de la livraison logicielle : du code qui fonctionne parfaitement sur un portable peut échouer partout ailleurs. Et plus le code s'éloigne de la machine du développeur, plus il devient difficile de diagnostiquer pourquoi.

Écrire du code qui voyage

Pour créer du code capable de dépasser le cadre d'un seul portable, les développeurs doivent écrire avec discipline. Pas à cause de règles ou de processus, mais parce que le code qui reste sur une seule machine est inutile pour tous les autres.

La première discipline est la gestion des dépendances. Chaque bibliothèque, framework et outil dont le code a besoin doit être enregistré explicitement. Pas installé manuellement et oublié. Pas supposé présent. Écrit dans un fichier de configuration qu'un autre développeur ou un serveur peut lire et installer automatiquement. Si le code nécessite une version spécifique d'une bibliothèque, cette version doit être épinglée. S'il a besoin d'un outil système, cet outil doit être documenté.

Par exemple, un projet Node.js déclare ses dépendances dans un fichier package.json comme ceci :

{
  "name": "my-app",
  "version": "1.0.0",
  "dependencies": {
    "express": "4.18.2",
    "pg": "8.11.3",
    "lodash": "4.17.21"
  },
  "devDependencies": {
    "jest": "29.7.0",
    "eslint": "8.56.0"
  }
}

La deuxième discipline est la séparation de la configuration. Les adresses de bases de données, les clés API, les chemins de fichiers et les paramètres spécifiques à l'environnement ne doivent jamais être codés en dur dans les fichiers sources. Ils appartiennent aux variables d'environnement ou aux fichiers de configuration chargés à l'exécution. Ainsi, le même code peut fonctionner sur le portable d'un développeur, un serveur de test et la production sans modification. Seule la configuration change.

La troisième discipline est de conserver un historique des modifications. Chaque fois qu'un développeur termine un travail logique cohérent, il sauvegarde cet état. En pratique, cela signifie faire un commit. Un commit est un instantané des modifications d'un ou plusieurs fichiers qui forment une unité cohérente. Ajouter un bouton de sauvegarde ? Le commit doit inclure le changement frontend, le point d'accès backend et les tests associés. Pas la moitié du travail, ni des modifications non liées mélangées.

Les commits créent un historique. Plus tard, lorsque le code tourne en production et que quelque chose se casse, cet historique devient le premier endroit où regarder. Qui a changé quoi ? Quand ? Pourquoi ? Le message du commit doit répondre à ces questions.

Du local au partagé

Commiter du code dans un dépôt local est une bonne habitude, mais ce n'est pas suffisant. Le code est toujours sur une seule machine. Si ce portable meurt, le travail est perdu. Si un autre développeur doit examiner les modifications, il ne peut pas les voir. Si un système automatisé doit construire et tester le code, il n'y a pas accès.

L'étape suivante est de pousser le code vers un dépôt partagé. C'est un emplacement central auquel l'équipe peut accéder. C'est là que le code devient visible pour les autres. C'est là que les outils automatisés peuvent le récupérer. C'est là que le voyage de l'idée au logiciel en fonctionnement commence vraiment.

Une fois que le code atteint le dépôt partagé, il peut être vérifié, testé et transformé en quelque chose qui s'exécute sur un serveur. Mais avant cela, il y a une étape supplémentaire : le code doit être relu. Soit par une autre personne, soit par un outil automatisé. Cette relecture détecte les erreurs que le développeur d'origine a manquées. Elle garantit que le code respecte les normes de l'équipe. Elle confirme que le changement a du sens avant d'aller plus loin dans le pipeline.

L'écart entre le code fonctionnel et le code livrable

Il y a une différence entre le code qui fonctionne sur votre machine et le code prêt à être livré. L'écart n'est pas une question de compétence. C'est une question d'environnement. Le code qui n'a jamais tourné que sur un seul portable n'a pas été testé face à la réalité. Il n'a pas été validé par rapport à l'environnement partagé où il s'exécutera finalement.

Combler cet écart nécessite des habitudes qui ressemblent à des frais généraux au début. Enregistrer les dépendances. Séparer la configuration. Faire des commits propres. Pousser vers un dépôt partagé. Chaque étape semble petite, mais ensemble, elles transforment le code de quelque chose de personnel en quelque chose qui peut être construit, testé et déployé par n'importe qui dans l'équipe.

Liste de contrôle pratique avant de pousser du code

Avant de pousser votre prochaine modification vers le dépôt partagé, passez en revue cette vérification rapide :

  • Toutes les dépendances sont-elles enregistrées dans un fichier de configuration pouvant être installé automatiquement ?
  • Les valeurs spécifiques à l'environnement (URL de base de données, clés API, chemins) sont-elles séparées du code ?
  • Le commit contient-il un changement logique unique, avec tous les fichiers associés inclus ?
  • Le message du commit explique-t-il ce qui a changé et pourquoi ?
  • Avez-vous exécuté le code dans un environnement propre correspondant à ce que le serveur utilisera ?

Si vous pouvez répondre oui aux cinq questions, le code est prêt à quitter votre portable.

La suite

Le code qui a été poussé vers un dépôt partagé n'est plus privé. Il est visible par l'équipe et disponible pour les processus automatisés. Mais ce n'est encore que du code. Il n'a pas été testé dans l'environnement réel. Il n'a pas été intégré avec d'autres modifications. Il n'a pas été transformé en un artefact déployable.

L'étape suivante consiste à vérifier que ce code fonctionne réellement lorsqu'il est combiné avec tout le reste. Cette vérification est le point de départ de l'intégration continue. Mais avant cela, les fondations doivent être solides : du code écrit en étant conscient qu'il quittera la machine du développeur pour s'exécuter ailleurs. Cette conscience est le premier vrai pas vers une livraison logicielle fiable.