Continuous delivery
chez LesFurets.com

Ozan Gunalp

Ozan GUNALP

Contributeurs

  • Dimitri BAELI
  • Benjamin DEGERBAIX
  • Geoffrey BERARD
  • Arnaud PFLIEGER
  • Alexandre DUBREUIL

Le delivery chez LesFurets.com

On a un rythme de marathonien,
pas de sprinter

L'équipe IT est constituée de 25 développeurs, intégrés dans 3 features team.

Les développeurs ont des responsabilités devops, telles que la livraison en production, la gestion de la configuration des environnements, le monitoring, etc.

  • 2012 : Spring Scrum mensuel
    12 releases (build 15 minutes et selenium 1 heure)

  • 2013 : Sprint scrum hebdo
    45 releases (build 3 minutes, release 1 jour)

  • 2014 - 2016 : Flux Kanban livraison quotidienne
    208, 217, 220+ releases (release 2 heures)

  • 2017+ : release par feature, release partial

Exigences

Pour passer en daily delivery, on a besoin de certains éléments préalables

  • Gestion de code source flexible
  • Integration continue
  • Build rapide et automatique avec des tests fiables
  • Gestion des artéfacts
  • Déploiement automatique
  • Monitoring & Alerting

Gestionnaire de logs : Graylog

Monitoring technique : Datadog

Monitoring fonctionnel : Graphite et Tessera

Monitoring graphique UI : LesFurets Zeno pixel
https://github.com/lesfurets/zeno-pixel

Déploiement blue / green, 0 downtime, avec HAProxy

Gestion de migration de base de données avec Flyway

Provisioning des machines avec Ansible

Tests fonctionnels Selenium

Normalement, nos 200 tests selenium prendraient 6 heures. Avec un grid selenium classique, on arrive à 1 heure

Avec un grid selenium en RAMFS ? 10 minutes

LesFurets selenium grid :
https://github.com/lesfurets/selenium-lxc

Gestion de code source

La manière de gérer son code source est important pour le delivery

Intégration continue Jenkins, TeamCity, Travis...


Intégration continue
=
intégrations fréquents
vérifications automatiques
détection d'erreur au plus tôt

http://paulhammant.com/2013/03/13/facebook-tbd-take-2/

Avec une code base en trunk based (option 1), toutes les features sont dans le master, ce qui permet de faire du build automatique et tous les commits sont envoyés en production à chaque release

Nécessite du feature toggling et une forte maturité sur l'infrastructure de test.

La migration vers le continuous delivery est un "big bang"

Avec une code base en feature branching (option 2), chaque feature est sur une branche dédiée, la prochaine release est la fusion du master et des features, les développements avancent en isolation, et on livre une branche lorsqu'elle est prête.

On perd l'intégration continue et la gestion des conflits

feature branching : on part d'un master

feature branching : création d'une branche de développement features/f1

feature branching : création d'une branche de développement features/f2

Merge pre-build : merge de master sur la branche avant le build.
Les outils IC permettent de faire le merge simple automatique.

On veut une code base en feature branching (pour sa flexibilité) et on veut faire du continuous delivery (pour sa valeur ajoutée), sans perdre l'intégration continue.

Autrement dit, comment réconcilier feature branching et intégration continue ?

On fait du continuous merge !

Continuous merge

Le continuous merge nous permet de créer un environnement commun pour l'intégration continue

Feature branching : historiques indépendants de features/f1 et features/f2

Continuous merge : merge de features/f1 et features/f2 avec master

continuous merge : nouveau commit sur features/f1

continuous merge : fusion automatique


# Fusion plusieurs branches avec pattern
git merge features/*
          

Mais le merge de plusieurs branches à partir d'un pattern n'existe pas dans git...

LesFurets git-octopus :
https://github.com/lesfurets/git-octopus

Intégration continue

Livre ce qui est prête avec feature branching

Peu d'investissements pour mettre en place
(Git, Jenkins, git-octopus)

Plus facile à appliquer que le trunk based

Passe à l'echelle

+

On constitue facilement les environnements

dev avec toutes les features
stage pour la validation
preprod pour les tickets validés

Si la probabilité d'avoir un conflit entre 2 branches est C,
Quelle est la probabilité d'avoir au moins un conflit lorsqu'on merge N branches?


Et comment gérer les conflits ?

gestion des conflits

gestion des conflits : une nouvelle branche sauvage features/new apparaît

gestion des conflits : git-octopus merge KO

gestion des conflits : git merge simple master et features/new OK

gestion des conflits : git merge simple features/f1 et features/new OK

gestion des conflits : git merge simple features/f2 et features/new KO

Gestion de conflits

L'utilisation de git-octopus dans l'intégration continue permet de détecter et éviter les conflits

Solution 1

éviter le conflit au niveau du code

éviter les conflits : git-octopus features/* KO à cause de features/new

éviter les conflits : modifier le code de features/new pour éviter le conflit

éviter les conflits : git-octopus features/* OK

Eviter le conflit au niveau code

Conventions de code partagées, éviter les binaires, un code base modulaire, évolutions par abstraction, SOLID

DANGER: safe

Solution 2

enlever la branche de l'octopus

sortir de l'octopus : git-octopus features/* KO à cause de features/new

sortir de l'octopus : utilisation du pattern de nommage pour sortir la branche

sortir de l'octopus : git-octopus features/* OK

Enlever la branche de l'octopus

Séparer les branches de longues durée, reprioriser la tâche.

DANGER : safe

Solution 3

fusionner la branche

fusionner la branche : git-octopus features/* KO à cause de features/new

fusionner la branche : fusion de features/f2 et features/new en features/f2_new

fusionner la branche : suppression de features/f2 et features/new

fusionner la branche : git-octopus features/* OK

Fusionner la branche

Coupler la livraison de deux branches.

DANGER : danger

Solution 4

rebaser la branche

rebaser la branche : git-octopus features/* KO à cause de features/new

rebaser la branche : rebase de feature/new sur features/f2

rebaser la branche : git-octopus features/* OK

Rebaser la branche

Surveiller les évolutions ultérieures de la branche de base.

DANGER :danger

Solution 5

git-conflict : résolution de conflit distribué, livré avec
git-octopus

git-conflict : git-octopus features/* KO à cause de features/new

git-conflict : dépôt résolution de conflit situé sous conflict/resolutions

git-conflict : git merge simple features/f2 et features/new KO

git-conflict : git-octopus regarde s'il y a une résolution de conflit disponible

git-conflict : git-octopus features/* OK

git-conflict

Permet l'évolutions indépendants des branches.
Nécessite de surveiller le contenu des resolutions de conflit.

DANGER : warning

En résumé...

1 : éviter les conflits

2 : enlever la branche de l'octopus

3 : utiliser git-conflict

4 : rebaser les branches

5 : fusionner les branches

6 : ...

Process chez LesFurets.com

L'objectif est de pouvoir prendre le temps de valider et de pouvoir livrer une feature dès qu'elle est prête

Demo

Ajoutez git-octopus à votre CI dès maintenant !

        
# Linux & Cygwin
git clone git@github.com:lesfurets/git-octopus.git
cd git-octopus && make install
# Mac
brew update
brew install git-octopus
        
      

Références

Code source git-octopus sur github
https://github.com/lesfurets/git-octopus

Forum git-octopus sur Google Groups
https://groups.google.com/forum/#!forum/git-octopus

Page conférences sur github
https://github.com/lesfurets/lesfurets-conferences