Continuous Integration, Delivery

CI

CI est la partie où le workflow doit valider chaque commit des développeurs automatiquement.

Les test unitaires et fonctionnels automatique sont valider par la machine d’intégration par exemple le CI de GitLab ou CircleCi. Une fois que les tests sont passés une build/artefact est produite et sera déployer dans l’environement de TEST.

Pour arriver à une build/artefact

  • Le code est construit à chaque commit
  • Le code est automatiquement soumis à des tests unitaires à chaque commit
  • Tout le monde a accès au rapport de construction et de test
  • Les tests sont exécutés sur une version réduite de l’environnement de production
  • Les artefacts livrables sont stockés dans un dépôt d’artefacts contrôlé par version
  • Les artefacts livrables sont automatiquement déployés dans un environnement de test après une construction réussie

Si une des étapes échoue alors le développeur responsable du commit reçoit une notification pour corriger le plus rapidement possible.

La mise en place d’une CI et l’ensemble des processus à intégrer

Les différents type de tests

  • Les tests Unitaires sont la pour test les méthodes ou les fonctions de manière
  • Les tests d’intégration sont la pour s’assurer que plusieurs composants se comportent correctement ensemble, ils sont pour les régressions fonctionnelles
  • les tests d’acceptation similaire que l’intégration mais axés sur l’activité
  • les tests interface utilisateur sont la pour s’assurer que du point de vue utilisateur les actions de l’interface fonctionnent
plus les tests sont basés sur la couche UI plus ils prennent du temps à être implémenter et maintenir, ils sont donc coûteux.

Pour adopter l’intégration continue, vous devrez exécuter vos tests sur chaque branche poussé.

Pour cela quelques questions simple:

  • où le code est-il hébergé? Restriction…
  • de quel système d’exploitation et de quelles ressources avons-nous besoin pour l’application? Dépendances…
  • de combien de ressources avons-nous besoin pour vos tests?
  • l’application est elle monolithique ou micro-service?
  • utiliser vous des conteneurs? Docker…

La couverture de Test & complexité

Il est bon de viser une couverture supérieure à 80% mais attention à ne pas confondre un pourcentage élevé de couverture avec une bonne suite de tests. Un outil de couverture de code nous aide à trouver le code non testé. La qualité de vos tests fera la différence à la fin de la journée.
Un outil comme SonarQube est là pour aider à prendre des décisions lorsque le code est complexe et non testé.

Duplication et code mort

Le code dupliqué sera le futur code mort ou le futur bug doublement corrigé ! Il est très important de vérifier votre code et de réduire les duplications maximum 5% de code dupliqué sur un gros projet ou un projet legacy est acceptable mais il faut essayer d’être en dessous de 2% pour tout projet commencer avec des métriques de code qualité.

Refactoring

Si vous êtes sur le point d’apporter des changements significatifs à votre application qui n’a pas de couverture de test suffisante, vous devriez commencer par écrire des tests d’acceptation autour des fonctionnalités qui pourraient être impactées. Cela vous fournira un filet de sécurité pour vous assurer que le comportement original n’a pas été affecté après le refactoring ou l’ajout de nouvelles fonctionnalités.

L’environment

Toute l’équipe informatique Dev/DevOps/Admin doit avoir à l’esprit de garder le même environnement partout. Le numéro de révision de tous les composants utilisés par l’application doit être le même dans Dev/Build/Test/Intégration/Prod. c’est là que les conteneurs (Docker) et les orchestrateur (Kubernetes) sont utiles.

L’état d’esprit

Si un développeur casse le workflow du CI, la réparation devient la priorité principale.

Pour écrire de bons tests, vous devrez vous assurer que les développeurs sont impliqués et on un accès à un outils d’analyse de code.

Que vous disposiez d’une base de code existante ou que vous débutiez, il est certain que des bogues surviendront dans le cadre de vos versions. Veillez à ajouter des tests lorsque vous les résolvez afin d’éviter qu’ils ne se reproduisent.

CD

Le déploiement de l’application est géré par le code. Le code décrit exactement ce dont l’application a besoin pour démarrer et s’exécuter. L’artefact et l’environnement seront les mêmes entre les systèmes Test/Intégration/Production car l’image est générée une seule fois par le CI.

Continuous Delivery

Après l’automatisation de la création et des tests unitaires et d’intégration dans le cadre de l’intégration continue, la continuous delivery automatise la publication du code validé dans un registry/repository. Aussi, pour garantir l’efficacité du processus de continuous delivery, il faut d’abord introduire le processus continuous delivery dans le pipeline de développement. La continuous delivery permet de disposer d’une base de code toujours prête à être déployée dans un environnement de production.

Dans le cadre de la continuous delivery, chaque étape (de la fusion des modifications de code jusqu’à la distribution des versions prêtes pour la production) implique l’automatisation des processus de test et de publication du code. À la fin de ce processus, l’équipe d’exploitation est en mesure de déployer facilement et rapidement une application dans un environnement de production.

Continuous Deployment

L’étape finale d’un pipeline CI/CD mature est le continuous deployment. En complément du processus de continuous delivery, qui automatise la publication d’une version prête pour la production dans un référentiel de code, le continuous deployment automatise le lancement d’une application dans un environnement de production. En l’absence de passerelle manuelle entre la production et l’étape précédente du pipeline, le déploiement continu dépend surtout de la conception de l’automatisation des processus de test.

Dans la pratique, dans le cadre du continuous deployment, une modification apportée par un développeur à une application pourrait être publiée quelques minutes seulement après la rédaction du code en question (en supposant qu’elle passe les tests automatisés). Il est ainsi beaucoup plus facile de recevoir et d’intégrer en continu les commentaires des utilisateurs. Ensemble, ces trois pratiques CI/CD réduisent les risques liés au déploiement des applications, puisqu’il est plus simple de publier des modifications par petites touches qu’en un seul bloc. Cette approche nécessite néanmoins un investissement de départ considérable, car les tests automatisés devront être rédigés de manière à s’adapter à un large éventail d’étapes de test et de lancement dans le pipeline CI/CD.

PHP Framework

La question que ce pose beaucoup de personne lorsque vous avez choisi comme langage pHp.

Il existe plusieurs Framework je vais vous présenter ceux que j’utilise mais les autres sont tout aussi valable en fonction de votre besoin. Symfony et Laravel sont très complet d’autre sont plus simple à mètre en place et pour des petites équipes.

Comparaison des deux Framework.

Les moteurs HTML Twig vs Blade

  • Lavravel propose d’écrire des fichiers .blade.php qui sont des fichiers PHP avec quelques méthodes supplémentaires pour vous simplifier la vie tel que @foreach ou @extends. Le code à l’intérieur des balises Bande doit avant tout être du code PHP
  • Symfony utilise le moteur de template Twig qui lui propose une syntaxe complètement différente du PHP. par exemple l’objet item.name au lient de $item.name qu’il est possible d’étendre grâce à l’utilisation d’extensions. (Vous ne pouvez pas faire appel à n’importe qu’elle class PHP depuis le template)

Twig est une moteur plus puissant mais est aussi contraignant en important l’utilisation d’extension pour rajouter des fonctionna litées. Cette aporche rand aussi les templates plus simplement éditable par les développeur front-end (la syntaxe est plus simple et ressemble à du JavaScript).

Balde est plus facile à prendre en main car permet d’écrire du PHP, avec le risque parfois de voir des appels aux models directement dans les vues.

ORM Doctrine vs Eloquent

  • Laravel utilise par défaut Eloquent qui est un ORM basé sur Active Record où le Model est à la fois responsable de représenter une entité, mais aussi de gérer la persistance des informations
  • Symfony utilise par défaut Doctrine qui est ORM basé sur le principe du Data Mapper où on sépare la notion d’entité (objet représentant les données), de Repository (objet servant à manipuler les entités) et de Manager (objet responsable de la persistance)

Eloquent a une syntaxe plus coutre et logique qui semple plus naturelle mais cette apparente simplicité peut rapidement mener à des « fat models » car toute la logique va être stocké au même endroit.

Doctrine permet naturellement une meilleur séparation mais s’avérera relativement verbeux pour des cas simples.

La gestion des formulaires FormBuilder vs FormRequest

  • Symfony permet de créer une class qui va gérer les formulaires, depuis leur création jusqu’au traitement des données. Le formulaire sera me capable d’hydrater une entitée à partir des données reçues
  • Laravel propose simplement un type de Request particulier permettant de vérifier et de traiter les données reçues lors d’un requête. il faudra alors manuellement traiter les données et les modifier me modèle en fonction

Ajouter de module Bundle vs ServiceProvider

  • Symfony est connu pour disposer d’un système de Bundle permettant l’ajout de fonctionnalitées supplémentaire simplement avec une bonne séparation du code
  • Laravel ne dispose pas d’un tel système mais il est possible de limiter avec utilisation les ServiceProviders qui disposent d’une méthode boot(). il est ainsi possible de créer une librairie dans un namespace séparer et d’inclure une logique dès l’importation du ServiceProvider

L’intégration de module par composer fonctionne dans les deux Framework.

Au final

Laravel se focalise sur la simplicité du code pour le développeur ce qui peut parfois amener à de mauvaises pratiques lorsque l’on veut prendre des raccourcis. Mais avec un peu de rigueur vous aurez un code propre et une bonne organisation de code. L’utilisation d’un Service Container permet de gérer l’injection de dépendance et ainsi s’assurer que le code reste facilement testable.

Symfony impose plus de rigueur et est plus complexe à appréhender. Il possède une courbe d’apprentissage un peu plus longue mais a l’avantage d’imposer plus de restriction. Une fois passé la phase d’apprentissage et la découvert des différents Bundle fournis par le Framework est aussi productif qu’avec Laravel.

Le choix est en fonction de vos affinité vis à vis de la méthode utilisée.