Développement web

Bonnes pratiques de développement : uv, branches, commits propres et déploiement

Un projet fiable ne dépend pas seulement du talent de celui qui écrit le code : il dépend de ce qui entoure le code. Un environnement qui se reconstruit à l’identique, un historique lisible, des contrôles qui s’exécutent avant qu’une erreur n’arrive en production, un déploiement qui ne repose pas sur une manipulation manuelle. Voici les habitudes que j’applique dans mes projets, avec des exemples tirés de mon organisation réelle, et ce qu’elles évitent.

1. Un environnement reproductible avec uv

Le classique « ça marche chez moi » vient presque toujours d’un environnement différent : une version de langage, une bibliothèque mise à jour entre-temps. Pour mes projets Python, j’utilise uv pour tout : installer les dépendances, lancer les commandes, exécuter les contrôles. Les dépendances sont verrouillées dans un fichier de verrouillage versionné : deux personnes, ou deux machines, obtiennent le même environnement. La règle est simple et sans exception chez moi : pas d’installation manuelle de paquets, pas d’environnement virtuel monté à la main.

2. Le dépôt comme source de vérité

Le dépôt contient tout ce qui permet de reconstruire et de comprendre le projet : le code, les tests, la documentation, la configuration de déploiement, les règles de contribution. Il ne contient jamais de secret : les mots de passe, clés et fichiers d’environnement restent hors du dépôt, avec un fichier d’exemple contenant uniquement des valeurs fictives. Un outil de détection de secrets s’exécute avant chaque commit, comme dernier filet.

Un dépôt bien tenu rend aussi le projet transmissible : quelqu’un d’autre peut le cloner, lire le README et le faire tourner.

3. Imposer de bons commits : pre-commit et commitizen

Un historique de commits est un journal de bord. S’il est lisible, on retrouve en quelques secondes pourquoi une ligne a changé. Pour l’obtenir sans compter sur la discipline de chacun, je m’appuie sur deux outils :

  • pre-commit exécute des contrôles à chaque commit : formatage, analyse du code, détection de secrets, fichiers trop volumineux. Si un contrôle échoue, le commit n’a pas lieu.
  • commitizen impose le format des messages, les Conventional Commits : un type, éventuellement une portée, puis une description (par exemple « feat(contact) : ajout du formulaire »). Chez moi, le type est en anglais et la description en français.

Ces messages réguliers servent ensuite à autre chose qu’à la lecture : commitizen en déduit le numéro de version (une nouvelle fonctionnalité fait monter la version mineure, une correction la version corrective, un changement incompatible la version majeure) et génère le journal des modifications. Et je n’utilise jamais l’option qui contourne les contrôles : si un contrôle gêne, on corrige la cause.

Pour des collaborateurs, c’est précieux : les mêmes règles s’appliquent à tous, sans relecture manuelle pour vérifier la forme, et la relecture peut se concentrer sur le fond.

4. Décomposer les branches

Je pratique un flux de branches identique sur tous mes projets applicatifs :

BrancheRôle
mainLa production. Aucun commit direct ; elle porte les étiquettes de version.
developLa préproduction, où l’on teste avant de livrer.
feature/…, fix/…, chore/…Le travail en cours, une branche par sujet, tirée de develop.
release/…La candidate de livraison, où l’on fixe le numéro de version et le journal des modifications.
Le flux de branches

Le cycle est le suivant : on travaille sur une branche de sujet, on la fusionne dans develop, on prépare une branche de livraison, on la teste en préproduction, puis on la fusionne dans main avec une étiquette de version. Chaque étape a un seul objectif, ce qui rend les retours en arrière simples. Un script d’aide enchaîne ces opérations pour éviter les erreurs de manipulation, et il ne publie rien sur le serveur sans demande explicite.

5. Des contrôles locaux avant tout

Les tests et l’analyse du code tournent sur ma machine, avant de pousser. Le retour est immédiat, et rien ne part sur le serveur sans avoir passé les contrôles. Le serveur d’intégration continue ne sert, chez moi, qu’au déploiement : il ne remplace pas les tests locaux. Ce choix limite la dépendance à un service externe et rend les erreurs moins coûteuses : on les voit en quelques secondes, pas après une file d’attente.

6. Le déploiement CI/CD vers un serveur

L’intégration et le déploiement continus (CI/CD) automatisent le chemin entre le code validé et le serveur. Dans mon organisation :

  • la fusion dans develop déclenche un déploiement en préproduction ;
  • la fusion dans main, avec son étiquette de version, déclenche le déploiement en production ;
  • les accès au serveur et les paramètres sensibles sont des variables protégées de la plateforme, jamais écrites dans le dépôt ;
  • rien n’est poussé, étiqueté ni déployé sans demande explicite de ma part.

L’intérêt de l’automatisation n’est pas la vitesse, mais la répétabilité : un déploiement fait toujours les mêmes opérations dans le même ordre, ce qu’une manipulation manuelle ne garantit jamais.

7. Ce que ces habitudes évitent

  • un correctif poussé directement en production sans test ;
  • une version impossible à retrouver parce qu’elle n’a pas été étiquetée ;
  • un secret publié par mégarde dans l’historique ;
  • des différences d’environnement entre le poste de développement et le serveur ;
  • un historique illisible où l’on ne sait plus pourquoi une ligne a changé.

Par où commencer

  1. Verrouiller les dépendances et documenter la commande de lancement.
  2. Ajouter pre-commit avec deux ou trois contrôles seulement, puis en ajouter peu à peu.
  3. Adopter le format des messages de commit, même seul.
  4. Séparer la production, la préproduction et le travail en cours.
  5. Automatiser le déploiement une fois que les étapes précédentes sont stables.

Une journée type

  1. Je tire une branche de sujet depuis develop avec le script d’aide.
  2. Je code, je lance les tests et l’analyse en local.
  3. Je commite avec l’assistant de commitizen : le type, la portée, la description. Pre-commit contrôle le formatage et les secrets.
  4. Je fusionne dans develop : la préproduction est mise à jour par la plateforme.
  5. Quand un lot est prêt, je prépare la branche de livraison : la version et le journal des modifications sont calculés à partir des messages de commit.
  6. Après validation en préproduction, la fusion dans main et l’étiquette de version déclenchent la production, sur demande explicite.

Intégrer un collaborateur

Ces habitudes facilitent l’arrivée d’une nouvelle personne. Elle clone le dépôt, exécute une commande pour reconstruire l’environnement, active les contrôles de commit, et suit le même flux que tout le monde. Les règles ne sont pas dans la tête de quelqu’un : elles sont dans des fichiers, appliquées automatiquement. La revue de code peut alors se consacrer à la logique, au lieu de relever des espaces en trop ou des messages de commit incompréhensibles.

Les pièges à éviter

  • Trop de contrôles d’un coup : l’équipe finit par les contourner. Mieux vaut un petit nombre de contrôles rapides, qui restent respectés.
  • Des branches qui vivent trop longtemps : plus elles divergent, plus la fusion est pénible. Des branches courtes, fusionnées souvent.
  • Des tests uniquement sur le serveur : on attend, on perd le fil. Les contrôles locaux donnent un retour immédiat.
  • Un déploiement que seul son auteur comprend : il doit être décrit dans la documentation du dépôt.

Documenter pour durer

Toutes ces pratiques perdent de leur valeur si personne ne sait les retrouver. Chaque projet contient donc un README qui explique comment l’installer, le lancer, le tester et le déployer, ainsi qu’un journal des modifications généré automatiquement. La règle que je m’impose : la documentation d’un changement est dans le même commit que le changement. Elle ne peut ainsi pas être oubliée, ni se périmer sans que ce soit visible dans l’historique.

En résumé

Ces pratiques ne sont pas réservées aux grandes équipes. Même seul, elles rendent un projet plus sûr et plus facile à reprendre. Elles s’accompagnent aujourd’hui d’un assistant comme Claude, dont le cadre se règle par des fichiers de configuration versionnés : j’en parle dans Claude dans un projet de développement.

Un projet à fiabiliser ?

Si vous voulez mettre en place ces pratiques sur vos développements, décrivez-moi votre contexte : je vous réponds avec une proposition sur devis.

Demander un devis