Continuous Deliver

Avant de parler du continous delivery, il est important dans un premier temps de rappeler l’intégration continue :

L'intégration continue
L'intégration continue est un ensemble de pratiques utilisées en génie logiciel consistant à vérifier à chaque modification de code source que le résultat des modifications ne produit pas de régression dans l'application développée. Bien que le concept existât auparavant , l'intégration continue se réfère généralement à la pratique de l'extreme programming.

Pour appliquer cette technique, il faut d'abord que :
 * le code source soit partagé (en utilisant des logiciels de gestion de versions tels que CVS,Subversion, git, Mercurial, etc)
 * les développeurs intègrent des commit quotidiennement (au moins) leurs modifications
 * des tests d'intégration soient développés pour valider l'application (avec JUnit par exemple)

Un outil d'intégration continue est ensuite nécessaire, tel que TeamCity, CruiseControl ou Jenkins (fork de Hudson) pour le langage Java par exemple.

Les principaux avantages d'une telle technique de développement sont :


 * le test immédiat des modifications
 * la notification rapide en cas de code incompatible ou manquant
 * les problèmes d'intégration sont détectés et réparés de façon continue, évitant les problèmes de dernière minute
 * une version est toujours disponible pour un test, une démonstration ou une distribution

Pratiques

 * Maintenir un Dépôt unique de code source versionné
 * Automatiser les compilations
 * Rendre les compilations auto-testantes
 * Tout le monde commit tous les jours
 * Tout commit doit compiler le tronc trunk sur une machine d'intégration
 * Maintenir un cycle de compilation court
 * Tester dans un environnement de production cloné
 * Rendre disponible facilement le dernier exécutable
 * Tout le monde doit voir ce qui se passe
 * Automatiser le déploiement



Le Continuous Delivery : Qu’est ce que c’est ?
Il est déjà opportun de différencier deux notions : le Continuous Deployment du Continuous Delivery (Déploiement vs Livraison).

Le déploiement continue consiste à mettre en production à chaque changement, quelque soit le changement. La livraison continue, quand à elle, s’attache à raccourcir le cycle d’obtention de la valeur, en s’intéressant à l’intégralité de la chaîne (pipeline) permettant de créer cette valeur.

Afin de délivrer cette valeur, il est alors question d’automatiser les différentes étapes de son pipeline de façon à pouvoir déployer en production à tout moment. Car en premier lieu, il est surtout question d’être capable de déployer dès qu’on le souhaite, rapidement, souvent et ceci avec un risque minimal lié à la procédure (erreur humaine, problème lié à l’environnement, problème de package…).



Ainsi les grands acteurs du web (facebook, google, instagram, Netflix…) déploient en production plusieurs fois par jour, ce qui leur donnent une grande capacité de réaction et une optimisation du Time To Market.

A noter que de façon à pouvoir mettre en place le Continuous Delivery, il est indispensable d’assurer une grande qualité du code source produit et d’avoir confiance en la qualité de ce code source (et donc d’avoir des métriques). Et ceci, par la mise en place au sein de son projet des pratiques telles que les tests unitaires, le Behaviour Driven Development, l’intégration continue…

Pour permettre le Continuous Delivery, vous devez ainsi passer un certain nombre d’étapes comme une course d’obstacle. Ces obstacles peuvent être soit de type organisationnels, soit de type techniques. Certains de ces obstacles pourront être passés grâce à des méthodes bien connues, ou que l’on adaptera pour répondre précisément aux problématiques rencontrées. Pour d’autres, il sera nécessaire de mettre en place des outils spécifiques ou d’adopter des infrastructures plus moderne pouvant répondre à ces problématiques.

Le Continuous Delivery : Pourquoi ?
“Quand ça fait mal, il faut le faire souvent (if it hurts, do it more often)”

Il est effectivement important de souligner que la construction du livrable et son déploiement, même quand cela est fait automatiquement, sont des moments chargés “d’émotions” et lourd de sens. Il est même courant d’espacer au maximum ces livraisons afin d’atténuer la souffrance. On est alors en droit de se demander : A-t-on vraiment besoin de souffrir ? Comment gérer ces prises de risque afin de les supprimer ?

Livrer aussi souvent que possible, livrer du matin au soir, que chaque commit soit immédiatement mis en production est le but ultime. Plus vous livrez, plus vos packages seront petits et les risques amoindris. Plus vous livrez et plus votre rigueur sera grande, car il n’est plus question de réaliser certaines tâches “plus tard” ou de laisser des choses à faire qu’on oublie parfois et qui rendent les phases de livraisons plus complexes que prévues.

Alors vous vous dites peut être oui, mais… Si je n’ai pas envie de livrer cette fonctionnalité ? Ma réponse : Vous n’avez pas envie de livrer cette fonctionnalité ou vous n’avez pas envie de l’activer ?

Une des approches est de découpler la livraison de l’activation. On parle du pattern toggle feature pattern. La fonctionnalité est présente dans le logiciel qui est mis en production mais elle n’est pas disponible, ni utilisable. L’activation de la fonctionnalité est rendu paramétrable dans la configuration du logiciel. Bien évidemment cette approche a aussi ses défauts et donne lieu à du refactoring régulier afin d’enlever le code conditionnel une fois que la fonctionnalité est validée et utilisée. Le toggle feature permet aussi d’être au plus près du besoin métier : activer une feature à la demande. Cela permet par exemple de gérer au niveau du produit une activation de service plutôt que de porter cette complexité au niveau d’une organisation / coordination d’équipe et des plannings éventuels. Aussi vite que ce besoin n’est plus exprimé par le métier, le code d’activation/désactivation est supprimé, permettant de rester en adéquation avec le besoin fonctionnel.

Etat des lieux et définition du pipeline de votre projet
Une première étape lorsque vous voulez mettre en place le Continuous Delivery dans votre projet/entreprise est de faire un état des lieux de votre Pipeline (constitué par toutes les étapes à partir du besoin jusqu’à la mise en production) et d’estimer le temps passé lors de chaque étape. Il n’est pas question de faire un bing-bang : il faut faire évoluer étape par étape adressant les goulots d’étranglement les uns après les autres et savoir s’adapter au contexte de votre projet/entreprise.



Une fois que vous avez identifié les différentes briques de votre Pipeline, vous pourrez identifier quelles sont les étapes qui prennent le plus de temps, celles qui sont les plus douloureuses ou celles qui sont le plus obscures. Posez vous la question de ce qui est possible d’améliorer. Pour cela, identifiez les pratiques automatisées et les pratiques manuelles ainsi que ce qui empêche l’automatisation. Quelles sont les étapes qui vous demande le plus de temps. Quelles sont les étapes qui sont entièrement sous votre contrôle et celles qui sont dépendantes de décisions ou d’actions externes à votre projet.

De cet état des lieux, vous pourrez investiguer sur les causes de vos maux afin de les adresser. Vous vous rendrez probablement compte que certaines étapes sont très consommatrices de temps (en charge ou en délais) sans forcément donner un retour sur investissement.

Automate all the things – Il faut tout automatiser
Si vous vous posez la question de savoir qu’elle démarche appliquer la réponse est simple :



En effet, le continuous delivery prends tout son sens lorsque toutes les étapes du pipeline sont entièrement automatisées. Ainsi, lorsque toutes les étapes sont automatisées, le temps entre la première étape et la dernière étape peut être connu et garanti ( on n’est pas obligé d’attendre qu’une personne bien précise soit disponible pour pouvoir faire la livraison, chaque étape est rejouable à loisir et son temps d’exécution est mesuré et historisé). Il faut par ailleurs garder à l’esprit que, bien que toutes les étapes soient automatisées (c’est-à-dire qu’aucune intervention manuelle n’est nécessaire pour réaliser une étape du pipeline), il peut arriver que le déclenchement d’une ou plusieurs étapes soit faite manuellement du fait de contraintes fortes externe au projet ( validation par une entité externe à l’entreprise par exemple). Même si c’est le genre de cas qu’on cherchera particulièrement à éviter.

Les commandements de l’automatisation Tu automatiseras tout, absolument tout :


 * Tu n’installeras pas manuellement tes dépendances ;
 * Tu automatiseras ta build ;
 * Tu automatiseras tes tests ;
 * Tu ne configureras pas à la main;
 * Tu ne créeras plus de machine à la main ;
 * Tu n’interviendras pas pour livrer ;
 * Des métriques tu auras, tes machines tu monitoreras ;

Vous l’aurez compris, pour la mise en place du Continuous Delivery, il faut que tout soit automatisé et répétable. Ainsi, il faut adresser l’environnement de production (sa construction) dès le départ. De fait, dès la mise en place de l’intégration continue, il faut faire en sorte que l’environnement dans lequel se font les différents tests (unitaires, intégration, performance,…) soient fait dans un environnement identique, sinon le plus semblable possible à l’environnement de production, de façon à se rendre compte le plus tôt possible des problèmes potentiels liés à l’environnement.

Un pattern répandu qui peut être mis en place est l’Infrastructure As Code où l’environnement est mis en place grâce à des scripts de configuration. Pour cela on utilisera des outils permettant de simplifier ce travail (Puppet, Chef, Vagrant, Docker, …).

Donc plus rien ne doit rester une tâche manuelle, et tous les artefacts permettant la mise en production doivent ainsi être archivés dans le contrôleur de code source : les scripts de mise à jour de la base de donnée, la configuration des environnements, les scripts de déploiement, … Le Continuous Delivery, c’est aussi un rythme

Quel rythme pour le continuous delivery ? Quel changement implique-t-il ?
Une des interrogations des plus intéressantes qui nous pousse à avoir cette démarche, est de nous interroger, sur la valeur à donner à des fonctionnalités développées mais non encore mise en production. La réponse, brutale et non moins réalise, est : aucune.

Un des travers que nous pouvons rencontrer encore maintenant sur les projets, est de voir les fonctionnalités s’accumuler.

Toute cette perte de temps est causée parfois par le focus mis sur le développement de nouvelles fonctionnalités sans se soucier de leur livraison… Cette perte de temps est un travers fréquent lors de l’utilisation de la méthode Scrum où la vélocité est calculé par la capacité de l’équipe à produire du code et non pas de la valeur.

Nous pourrions proposer un nouveau principe : rendre votre produit déployable plutôt que livrer de nouvelle fonctionnalités puisque toute fonctionnalité non livrée n’amène pas de valeur.

Voir aussi

 * Jenkins (fork de Hudson), serveur d'intégration continue pour Java
 * Tinderbox, serveur d'intégration continue de la Mozilla Foundation
 * Apache Continuum, server de l'Apache Software Foundation
 * Team Foundation Server, serveur Microsoft
 * TeamCity

Liens externes

 * Continuous Integration par Martin Fowler
 * Apache Gump
 * CABIE
 * TeamCity
 * Travis CI propose un service d'intégration continue gratuit aux projets open sources.