Archives par étiquette : Continuous Delivery

Antidot Engineering practices

Software quality and robustness largely depend on the development methods in place. We can proudly say that Antidot applies state-of-the-art practices, with a constant effort to sharpen our methodology.

Software engineering

We apply state of the art techniques and good practices when coding. Our software is built using the continuous delivery paradigm.

  • Code is versioned in an internal Git source control system: all changes are logged and monitored
  • Our products are built using the latest versions of C++ , Java and Python (currently C++14, Java 8 and Python 3.5). We apply security patches and bug fixes to the third libraries that we use. Software is built using the continuous delivery paradigm
  • For every feature or bug fix, a topic branch is created. Jira epic/stories/tasks are created to track the development and our SCM tools (Gitlab CI and Jenkins) are linked to Jira.
  • A bug fix commit is not accepted without a test proving the issue is really fixed.
  • Code is written in pair mode and/or a merge request is created for review.
  • Code includes unit tests, functional tests and large tests involving all components.
  • These tests are run for every commit (several thousand tests).
  • Branches can be merged into a release branch only after review and if CI status is still ok.
  • Every commit on a release branch that leaves CI green (including large tests) creates an installation candidate. It usually takes about an hour for a valid commit to produce an installation candidate.
  • Each night additional tests that recreate a full day of production are run on the latest installation candidate, including stress and recovery tests.
  • Every week (or more often if required) we cherry pick the « best » candidate of the week (usually the latest) and deliver it to our customers (release note + updated package repository).

Code analysis

  • Code coverage and static analysis tools are frequently run (Sonar,CppCheck, SafeHTML …).
  • Penetration tools are frequently run.

DevOps

  • DevOps feedback loop provides quick feedback to developers about installation, upgrade or production issues.
  • Our Ops team can (and will) refuse to install a version if they are not confident with its quality.
  • Our Ops team uses state of the art monitoring and automated deployment tools (Puppet, Ansible, FAI …).  Our servers are regularly cleaned and reinstalled automatically.
  • Container technologies (LXD, Docker) are heavily used to isolate environments and to ensure that our software can be built, installed and run from a bare OS installation.
  • When preparing rollout of major update, DevOps transversal teams perform non-regression, performance and stress tests of the new binaries (“you build it, you run it”).
  • A/B techniques are used to progressively roll out new versions in our Cloud. Changes and user behavior are monitored in real time and can remove a new version from production if required without having the need to rollback software or databases.
  • Feature toggles enable progressive rollout of new features to selected customers.
  • HipChat rooms are used internally for efficient communication between Dev, Ops, internal Professional Services users, …

Agility

  • Teams work in Agile mode, using Scrum, Kanban or in-house mix of various Agile methods.
  • All teams use the same rhythm: iterations of 3 weeks, at the end of which retrospectives and review ceremonies are held.
  • Our managers and developers frequently attend Agile Tour meetings to challenge and update their skills.

Culture

  • Our developers are passionate, they attend several conferences per year (DockerCon, Fosdem, Devoxx …) and go to local meetups and JUGs.
  • Every week a developer talks in front of his peers of a specific technological topic (30 minutes).
  • Hackathons are held to foster innovation.
  • Frequent meetings are held between stakeholders (Product owner, Support and Professional Services managers, Pre-sales staff, Top management ….) to ensure that everybody is focused on providing value to our Customers.
  • Professional Services teams lead a review meeting after completion of customer’s projects. This review provides feedback to developers and ops, allow fine tuning of the backlogs. This also allow Support staff members to gain project knowledge.

Continuous integration, Continuous delivery, Continuous deployment : où en est-on chez Antidot ?

L’équipe Delivery a la responsabilité de la mise en place des outils et des process de l’équipe technique chez Antidot. Dans ce cadre, elle développe puis opère les chaînes d’intégration continues de nos produits logiciels.

Je me propose de vous faire un retour d’expérience basé sur notre pratique.

De quoi parle t-on ?

L’intégration continue (continuous integration dans la littérature anglo-saxonne) implique que les développements logiciels sont régulièrement intégrés sur une branche commune sur laquelle sont automatiquement déroulées toutes les étapes de compilation et de validation.

La livraison continue (continuous delivery) est la suite logique de l’intégration continue : elle implique qu’à chaque moment on est « prêt à livrer » une version. La sortie de l’intégration continue devient donc le livrable attendu.

Le déploiement continu (continuous deployment) représente le Graal des équipes DevOps : chaque commit, s’il n’introduit pas de régression, finit automagiquement en prod.

(source IamOnDemand)

Continuous Integration

Depuis 5 ans, nous avons mis en place des chaines d’intégration continues, de plus en plus complètes.

A ce jour, chaque commit dans git sur une des branches de référence déclenche séquentiellement :

  • La compilation et les tests smalls,
  • le packaging (.deb et .rpm) et la création de dépôts dédiés à la validation,
  • des tests dits « medium » puis des tests dits « larges ».

Les dénominations de tests « small », « mediums » et tests « larges » viennent de l’excellent livre « How Google tests software », dont vous trouverez ici un résumé en français et qui propose une classification des tests en small, medium et large.

  • Un test small valide une unique fonction, avec une granularité très fine
  • Un test medium implique un ensemble de « modules » qui collaborent pour réaliser une fonction
  • Un test large implique le système entier.

Les problèmes que nous avons rencontrés lors de la mise en place de ces chaines d’intégration continue tournent autour de deux thèmes :

  • L’instabilité chronique des chaines,
  • Le temps d’exécution de ces chaines.

La solution au premier point réside dans l’analyse systématique des erreurs pour essayer d’en éliminer les causes racines. Je pense qu’on pourrait faire un article entier (et d’ailleurs je le ferai peut être) sur toutes les raisons, bonnes ou mauvaises, qui font qu’une chaine d’intégration continue est instable.

Pour le second point, nous n’avons pas à ce jour de solution satisfaisante : après avoir facilité l’écriture de tests, mis en place des outils pour les jouer automatiquement, réussi à convaincre tout le monde de l’intérêt de produire un maximum de tests, nous sommes aujourd’hui confrontés au problème de l’adhésion de tous à ces principes, et donc nos suites de tests augmentent et leurs temps d’exécution s’allongent.

D’aucuns diront que c’est un problème de riche, mais il faudra assez rapidement que nous nous attaquions à ce problème.

Continuous Delivery && Continuous Deployment

Les chaines d’intégration continue installent toutes les nuits la meilleure version disponible (RC pour « Release Candidate ») dans un environnement simulant la production.

À tout instant, une version est donc prête à livrer, et en ce sens nous respectons le Continuous Delivery.

En pratique, nous livrons une version toute les semaines et chacune de ces versions est mise en production.

Qu’est ce que signifie livrer pour nous ?

  • positionner un numéro de version sur un SHA-1 git,
  • communiquer sur la disponibilité de cette version (mail, tweet),
  • communiquer (Release Notes) sur le contenu fonctionnel de la version : nouvelles fonctionnalités, corrections de bugs…
  • mettre à disposition des paquets dans un dépôt stable.

Pourquoi doit on livrer ?

La question peut surprendre, mais dans un monde où une part significative des développements est exploitée en mode Cloud, la notion de numéro de version peu avoir un coté archaïque. Si l’on applique à la lettre les principes du Continuous Deployment, la version en production est la dernière qui a passée toutes les validations, et la notion de livraison telle que décrite ci dessus s’estompe.

Pour autant, nous ne somme pas prêt à abandonner la notion de livraison car en plus d’opérer notre propre solution dans notre datacenter, nous livrons aussi  nos logiciels en licence et nous fournissons notre plateforme à des partenaires qui construisent des solutions par dessus.

Dans ces deux derniers cas, les clients peuvent attendre des fonctionnalités ou des corrections de défauts, qui doivent être corrélées à des versions.

Le Delivery Train

La pratique de livrer systématiquement toutes les semaines la meilleure version possible (la dernière ayant passée avec succès tous les tests disponibles) est inspirée du « Delivery train » prôné par Spotify. Par ailleurs, c’est un premier pas vers le « Continuous Deployment ».

Avant la mise en place du Delivery Train :

  • la livraison d’une version, son périmètre fonctionnel, sa date de sortie était le résultat d’âpres négociations entre développeurs et chefs de projet, arbitrées par l’équipe Delivery.

Depuis la mise en place du Delivery Train, la livraison est systématique le vendredi et cela a :

  • enlevé du travail inutile et chronophage de négociation de date et de contenu,
  • rassuré tout le monde : si on rate un créneau pour une correction, le suivant n’est jamais que dans une semaine dans le pire des cas,
  • fortement amélioré l’automatisation du mécanisme de livraison : ce sont les effets bénéfiques du classique : « if it hurts, do it more often » cher à toutes les pratiques d’automatisation
  • et donc bien évidemment, facilité le non respect de la règle : en cas d’urgence (bug critique…), nous relivrons immédiatement. Et les gains en automatisation du processus de livraison facilitent cette livraison supplémentaire.

Continuous Deployment

Antidot ne fait donc pas aujourd’hui de Continuous Deployment. Mais un des effets bénéfiques du Delivery Train est que l’on y va doucement mais sûrement, poussés par le train.

En effet, la mise à disposition toutes les semaines d’une nouvelle version, nous a poussé à essayer de la mettre en production dans la foulée.

Nous sommes à nouveau dans un mode « if it hurts do it more often » :

  • nous avons mis à plat les processus de mise en production,
  • nous avons systématisé un calendrier,
  • nous sommes actuellement en train de travailler à rendre ce process aussi automatique que possible.

À moyen terme notre objectif sera donc une livraison hebdomadaire de version et le déploiement automatique de cette version sur notre production.

Je ne sais pas dire aujourd’hui si nous irons vers le Continuous Deployment au sens strict de la définition. Je dirais que nous n’en n’avons jamais été aussi près, et je vous en reparlerai dans quelques mois, lorsque nos objectifs moyens termes seront atteints.

Références :