Pas 11: Ramificarea Codului

5.0 version
Maintained

Ramificarea Codului

Sunt multe modalități de a organiza fluxul modificării de cod într-un proiect. Dar lucrul direct asupra ramurei principale Git și lansarea directă în producție fără testare nu este probabil cea mai bună.

Testarea nu înseamnă doar teste unitare sau funcționale, ci și verificarea comportamentului aplicației cu date de producție. Dacă tu sau stakeholderii pot testa aplicația exact așa cum va fi pentru utilizatorii finali, acest lucru devine un avantaj uriaș și îți permite să lansezi aplicația fără temeri. Este extraordinar de util atunci când oamenii pot valida funcții noi fără să aibă nevoie de aptitudini tehnice.

O să continuăm să folosim ramura principală în Git (master), de dragul simplității și pentru a evita repetiția inutilă, dar hai să vedem cum ar fi altfel.

Adoptarea unui flux de lucru în Git

Unul din fluxurile de lucru posibile este crearea unei ramuri (branch) pentru fiecare caracteristică nouă sau pentru fiecare eroare. Așa este mai simplu și eficient.

Descrierea infrastructurii

S-ar putea să nu îți fi dat seama încă, dar faptul că infrastructura este stocată în fișiere alături de cod ajută foarte mult. Docker și SymfonyCloud folosesc fișiere de configurare pentru a descrie infrastructura proiectului. Când o caracteristică nouă are nevoie de un serviciu suplimentar, modificările de cod și modificările de infrastructură se fac în același loc, într-un singur pas.

Crearea ramurilor

Fluxul de lucru începe prin crearea unei ramuri în Git:

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

Această comandă creează o ramură sessions-in-redis din ramura master. Aceasta este o „bifurcație” a codului și a configurației infrastructurii (fork).

Stocarea sesiunilor în Redis

După cum probabil ai ghicit de la numele ramurei, dorim să schimbăm stocarea sesiunii de la sistemul de fișiere la un sistem de stocare Redis.

Pașii necesari sunt simpli:

  1. Creează o ramură Git;
  2. Actualizează configurația Symfony dacă este necesar;
  3. Scrie și/sau actualizează codul dacă este necesar;
  4. Actualizează configurația PHP (adaugă extensia PHP Redis);
  5. Actualizează infrastructura de pe Docker și SymfonyCloud (adaugă serviciul Redis);
  6. Testează local;
  7. Testează pe serverul de la distanță;
  8. Îmbină versiunea ta cu cea din ramura principală;
  9. Lansează în producție;
  10. Șterge ramura ta.

Toate modificările necesare de la 2 până la 5 se pot face într-un singur 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]

Nu-i așa că e frumos?

„Repornește” containerele Docker pentru a porni serviciul Redis:

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

Te las să testezi local navigând pe site. Deoarece nu există modificări vizuale și pentru că nu folosim încă sesiuni, totul ar trebui să funcționeze ca înainte.

Lansarea codului dintr-o ramură

Înainte de a lansa pe producție, ar trebui să testăm ramura pe o infrastructură similară celei de producție. De asemenea, ar trebui să validăm că totul funcționează bine pentru mediul Symfony prod (site-ul local folosește mediul Symfony dev).

În primul rând, asigură-te că salvezi modificările tale în noua ramură:

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

Acum, hai să creăm un mediu SymfonyCloud bazat pe ramura Git:

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

Această comandă creează un mediu nou după cum urmează:

  • Ramura moștenește codul și infrastructura de la ramura Git curentă (sessions-in-redis);
  • Datele provin din mediul principal (adică cea folosită în producție), salvând o copie completă a tuturor datelor, inclusiv fișiere (fișierele încărcate de utilizatori, de exemplu) și baze de date;
  • Un nou cluster dedicat este creat pentru a lansa codul, datele și infrastructura.

Întrucât lansarea curentă urmează aceleași etape ca lansarea ulterioară pentru producție, migrațiile bazei de date vor fi, de asemenea, executate. În acest fel, vei valida că migrațiile funcționează cu datele din producție.

Mediile care nu sunt master sunt foarte asemănătoare cu master, cu excepția unor mici diferențe: de exemplu, e-mailurile nu sunt trimise implicit; trimiterea lor e doar simulată.

După terminarea implementării, deschide site-ul într-un browser pentru a testa noua ramură:

1
$ symfony open:remote

Reține că toate comenzile SymfonyCloud funcționează pe ramura Git curentă. Aceasta va deschide URL-ul implementat pentru ramura sessions-in-redis - adresa URL va arăta ca https://sessions-in-redis-xxx.eu.s5y.io/).

Testează site-ul web în acest nou mediu. Ar trebui să vezi toate datele pe care le-ai creat în mediul principal.

Dacă adaugi mai multe conferințe pe mediul master, acestea nu vor apărea în mediul sessions-in-redis și vice-versa. Mediile sunt independente și izolate.

Dacă codul evoluează pe master, poți întotdeauna să refaci ramura Git și să implementezi versiunea actualizată, rezolvând conflictele atât pentru cod, cât și pentru infrastructură.

Poți chiar să sincronizezi datele din master în mediul sessions-in-redis:

1
$ symfony env:sync

Depanarea implementărilor de producție înainte de lansare

În mod implicit, toate mediile SymfonyCloud folosesc aceleași setări ca mediul master/prod (denumit, de asemenea, mediul Symfony prod). Acest lucru îți permite să testezi aplicația în condiții reale. Îți creează impresia că lucrezi direct pe serverele de producție, dar fără riscurile asociate. Acest lucru îmi amintește de vremurile bune când publicam proiectele prin FTP.

În cazul unei probleme, poți să treci la mediul dev Symfony:

1
$ symfony env:debug

După ce ai terminat, te întorci la setările de producție:

1
$ symfony env:debug --off

Atenționare

Niciodată nu activa mediul dev sau Depanatorul Symfony în ramura master; ar face ca aplicația ta să devină lentă și deschide o mulțime de vulnerabilități grave de securitate.

Testarea implementărilor de producție înainte de publicare

Accesul la versiunea viitoare a site-ului web cu date de producție deschide o mulțime de oportunități: de la testarea regresiei vizuale la testarea performanței. Blackfire este instrumentul perfect pentru job.

Consultă pasul despre „performanță” pentru a afla mai multe despre modul în care poți utiliza Blackfire pentru a testa codul tău înainte de publicare.

Fuziunea cu producția

Când ești mulțumit de modificările din ramura ta, îmbină modificările din cod și infrastructură înapoi în ramura principală Git printr-o fuziune:

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

Și publică:

1
$ symfony deploy

Când se lansează, doar modificările codului și infrastructurii sunt împinse către SymfonyCloud; datele nu sunt afectate în niciun fel.

Curățenie

La final, facem curățenie ștergând ramura din Git și mediul din SymfonyCloud:

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

  • « Previous Pas 10: Construirea interfeței pentru utilizator
  • Next » Pas 12: Ascultarea evenimentelor

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