Étape 11: Utiliser des branches

5.0 version
Maintained

Utiliser des branches

Il existe de nombreuses façons d’organiser le workflow des changements apportés au code d’un projet. Mais travailler directement sur la branche master de Git et déployer directement en production sans tester n’est probablement pas la meilleure solution.

Tester ne se résume pas à un test unitaire ou fonctionnel, il s’agit aussi de vérifier le comportement de l’application avec les données de production. Le fait que vous, ou vos collègues, puissiez utiliser l’application exactement de la même manière que lorsqu’elle sera déployée est un énorme avantage. Cela vous permet de déployer en toute confiance. C’est particulièrement vrai lorsque des personnes non-techniques peuvent valider de nouvelles fonctionnalités.

Par souci de simplicité et pour éviter de nous répéter, nous continuerons à travailler sur la branche master de Git dans les prochaines étapes, mais voyons comment nous pourrions améliorer cela.

Adopter un workflow Git

Un workflow possible est de créer une branche par nouvelle fonctionnalité ou correction de bogue. C’est simple et efficace.

Décrire votre infrastructure

Vous ne l’avez peut-être pas encore réalisé, mais avoir l’infrastructure stockée dans des fichiers à côté du code aide beaucoup. Docker et SymfonyCloud utilisent des fichiers de configuration pour décrire l’infrastructure du projet. Lorsqu’une nouvelle fonctionnalité nécessite un service supplémentaire, le code change et les changements d’infrastructure font partie du même patch.

Créer des branches

Le workflow commence par la création d’une branche Git :

1
$ git branch -D sessions-in-redis || true
1
$ git checkout -b sessions-in-redis

Cette commande crée une branche sessions-in-redis à partir de la branche master. Elle « fork » le code et la configuration de l’infrastructure.

Stocker les sessions dans Redis

Comme vous l’avez deviné d’après le nom de la branche, nous voulons passer du stockage de session dans le système de fichiers à un stockage Redis.

Les étapes nécessaires pour le faire sont classiques :

  1. Créez une branche Git ;
  2. Mettez à jour la configuration de Symfony si nécessaire ;
  3. Écrivez et/ou mettez à jour le code si nécessaire ;
  4. Mettez à jour la configuration PHP (ajoutez l’extension Redis PHP) ;
  5. Mettez à jour l’infrastructure sur Docker et SymfonyCloud (ajoutez le service Redis) ;
  6. Testez localement ;
  7. Testez à distance ;
  8. Mergez la branche dans master ;
  9. Déployez en production ;
  10. Supprimez la branche.

Tous les changements nécessaires pour les étapes 2 à 5 peuvent être effectués en un seul patch :

patch_file
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
--- a/.symfony.cloud.yaml
+++ b/.symfony.cloud.yaml
@@ -15,8 +15,13 @@ runtime:
 build:
     flavor: none

+variables:
+    php-ext:
+        redis: 5.3.1
+
 relationships:
     database: "db:postgresql"
+    redis: "rediscache:redis"

 web:
     locations:
--- a/.symfony/services.yaml
+++ b/.symfony/services.yaml
@@ -2,3 +2,6 @@ db:
     type: postgresql:11
     disk: 1024
     size: S
+
+rediscache:
+    type: redis:5.0
--- a/config/packages/framework.yaml
+++ b/config/packages/framework.yaml
@@ -7,7 +7,7 @@ framework:
     # Enables session support. Note that the session will ONLY be started if you read or write from it.
     # Remove or comment this section to explicitly disable session support.
     session:
-        handler_id: null
+        handler_id: '%env(REDIS_URL)%'
         cookie_secure: auto
         cookie_samesite: lax

--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -8,3 +8,7 @@ services:
             POSTGRES_PASSWORD: main
             POSTGRES_DB: main
         ports: [5432]
+
+    redis:
+        image: redis:5-alpine
+        ports: [6379]

N’est-ce pas magnifique ?

« Redémarrez » Docker pour démarrer le service Redis :

1
2
$ docker-compose stop
$ docker-compose up -d

Je vous laisse tester localement en naviguant sur le site. Comme il n’y a pas de changement visuel et que nous n’utilisons pas encore les sessions, tout devrait continuer à fonctionner comme avant.

Déployer une branche

Avant le déploiement en production, nous devrions tester la branche sur la même infrastructure que celle de production. Nous devrions également valider que tout fonctionne bien pour l’environnement prod de Symfony (le site local utilise l’environnement dev de Symfony).

Tout d’abord, assurez-vous de commiter vos modifications dans la nouvelle branche :

1
2
$ git add .
$ git commit -m'Configure redis sessions'

Maintenant, créons un environnement SymfonyCloud basé sur la branche Git :

1
$ symfony env:delete sessions-in-redis --no-interaction
1
$ symfony env:create

Cette commande crée un nouvel environnement comme suit :

  • La branche hérite du code et de l’infrastructure de la branche Git actuelle (sessions-in-redis) ;
  • Les données proviennent de l’environnement master (c’est-à-dire la production) en prenant un instantané de toutes les données du service, y compris les fichiers (fichiers uploadés par l’internaute par exemple) et les bases de données ;
  • Un nouveau cluster dédié est créé pour déployer le code, les données et l’infrastructure.

Comme le déploiement suit les mêmes étapes que le déploiement en production, les migrations de bases de données seront également exécutées. C’est un excellent moyen de valider que les migrations fonctionnent avec les données de production.

Les environnements autres que master sont très similaires à master, à quelques petites différences près : par exemple, les emails ne sont pas envoyés par défaut.

Une fois le déploiement terminé, ouvrez la nouvelle branche dans un navigateur :

1
$ symfony open:remote

Notez que toutes les commandes SymfonyCloud fonctionnent sur la branche Git courante. Cela ouvrira l’URL de la branche sessions-in-redis déployée. L’URL ressemblera à https://sessions-in-redis-xxx.eu.s5y.io/.

Testez le site web sur ce nouvel environnement. Vous devriez voir toutes les données que vous avez créées dans l’environnement master.

Si vous ajoutez d’autres conférences sur l’environnement master, elles n’apparaîtront pas dans l’environnement sessions-in-redis et vice-versa. Les environnements sont indépendants et isolés.

Si le code évolue sur master, vous pouvez toujours rebaser la branche Git et déployer la version mise à jour, résolvant ainsi les conflits tant pour le code que pour l’infrastructure.

Vous pouvez même synchroniser les données de master avec l’environnement sessions-in-redis :

1
$ symfony env:sync

Déboguer les déploiements en production avant de déployer

Par défaut, tous les environnements SymfonyCloud utilisent les mêmes paramètres que l’environnement master/prod (c’est à dire l’environnement Symfony prod). Cela vous permet de tester l’application dans des conditions réelles. Il vous donne l’impression de développer et de tester directement sur des serveurs de production, mais sans les risques qui y sont associés. Cela me rappelle le bon vieux temps où nous déployions par FTP.

En cas de problème, vous pouvez passer à l’environnement Symfony dev :

1
$ symfony env:debug

Une fois terminé, revenez aux réglages de production :

1
$ symfony env:debug --off

Avertissement

N’activez jamais l’environnement dev et n’activez jamais le Symfony Profiler sur la branche master ; cela rendrait votre application vraiment lente et ouvrirait de nombreuses failles de sécurité graves.

Tester les déploiements en production avant de déployer

L’accès à la prochaine version du site web avec les données de production ouvre de nombreuses opportunités : des tests de régression visuelle aux tests de performance. Blackfire est l’outil parfait pour ce travail.

Reportez-vous à l’étape « Performances » pour en savoir plus sur la façon dont vous pouvez utiliser Blackfire pour tester votre code avant de le déployer.

Merger en production

Lorsque vous êtes satisfait des changements de la branche, mergez le code et l’infrastructure dans la branche master de Git :

1
2
$ git checkout master
$ git merge sessions-in-redis

Et déployez :

1
$ symfony deploy

Lors du déploiement, seuls le code et les changements d’infrastructure sont poussés vers SymfonyCloud ; les données ne sont en aucun cas affectées.

Faire le ménage

Enfin, faites le ménage en supprimant la branche Git et l’environnement SymfonyCloud :

1
2
$ git branch -d sessions-in-redis
$ symfony env:delete --env=sessions-in-redis --no-interaction

  • « Previous Étape 10: Construire l’interface
  • Next » Étape 12: Écouter les événements

This work, including the code samples, is licensed under a Creative Commons BY-NC-SA 4.0 license.