Stap 11: Branching van de code
Branching van de code¶
Er zijn vele manieren om de workflow van codewijzigingen in een project te organiseren. Maar direct werken in de Git master-branch en direct in productie nemen zonder testen is waarschijnlijk niet de beste.
Testen gaat niet alleen over unit- of functionele testen, het gaat ook over het controleren hoe de applicatie zich gedraagt met productiegegevens. Als jij of jouw stakeholders de applicatie kunnen testen in dezelfde staat als aan de eindgebruikers opgeleverd zal worden, dan is dat een groot voordeel. Het maakt dat je met vertrouwen kan deployen. Het voordeel komt in het bijzonder tot zijn recht wanneer niet-technische mensen nieuwe features kunnen gaan valideren.
Om het eenvoudig te houden zullen we in de volgende stappen al ons werk in de Git master branch blijven doen. Maar laten we eens kijken hoe het eventueel ook beter kan.
Het eigen maken van een Git Workflow¶
Een mogelijke workflow is het creëren van een branch per nieuwe functie of bugfix. Dit is eenvoudig en efficiënt.
Jouw infrastructuur beschrijven¶
Je besefte het misschien nog niet, maar jouw infrastructuur kunnen bewaren in bestanden naast jouw code, is zeer handig. Docker en SymfonyCloud gebruiken configuratiebestanden om de projectinfrastructuur te beschrijven. Wanneer een nieuwe feature een extra service nodig heeft, dan veranderen zowel de code en de infrastructuurbestanden, in dezelfde patch.
Branches maken¶
De workflow begint met het aanmaken van een Git branch:
1 | $ git branch -D sessions-in-redis || true
|
1 | $ git checkout -b sessions-in-redis
|
Dit commando maakt een sessions-in-redis
branch aan vanuit de master
branch. Het maakt een afsplitsing van de code en de infrastructuurconfiguratie.
Sessies opslaan in Redis¶
Zoals je misschien - op basis van de branchnaam - geraden hebt, willen we de session-storage overschakelen van het filesystem naar Redis.
De stappen die nodig zijn om het te realiseren zijn logisch:
- Maak een Git branch aan;
- Werk de Symfony-configuratie bij indien nodig;
- Schrijf en/of update wat code indien nodig;
- Werk de PHP-configuratie bij (voeg de Redis PHP-extensie toe);
- Update de infrastructuur op Docker en SymfonyCloud (voeg de Redis-service toe);
- Lokaal testen;
- Remote testen;
- Merge de branch met de master branch;
- Deployen naar productie;
- Verwijder de branch.
Alle wijzigingen die nodig zijn voor stap 2 tot 5 kunnen in één patch gedaan worden:
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 47 48 | --- a/.symfony.cloud.yaml
+++ b/.symfony.cloud.yaml
@@ -4,6 +4,7 @@ type: php:7.4
runtime:
extensions:
+ - redis
- pdo_pgsql
- apcu
- mbstring
@@ -24,6 +25,7 @@ disk: 512
relationships:
database: "db:postgresql"
+ redis: "rediscache:redis"
web:
locations:
--- a/.symfony/services.yaml
+++ b/.symfony/services.yaml
@@ -2,3 +2,6 @@ db:
type: postgresql:13
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]
|
Is dit niet prachtig?
“Herstart” Docker om de Redis-service te starten:
1 2 | $ docker-compose stop
$ docker-compose up -d
|
Ik laat je lokaal testen door naar de website te surfen. Omdat er geen visuele veranderingen zijn en omdat we nog geen sessies gebruiken, zou alles nog steeds moeten werken zoals voorheen.
Deployen van een branch¶
Voordat we de branch in productie nemen, moeten we deze testen op dezelfde infrastructuur als in productie. We moeten ook valideren dat alles goed werkt voor de prod
Symfony-omgeving (de lokale website gebruikt de dev
Symfony-omgeving).
Zorg er eerst voor dat je jouw wijzigingen commit in de nieuwe branch:
1 2 | $ git add .
$ git commit -m'Configure redis sessions'
|
Laten we nu een SymfonyCloud-omgeving maken op basis van de Git branch:
1 | $ symfony env:delete sessions-in-redis --no-interaction
|
1 | $ symfony env:create
|
Dit commando creëert vervolgens een nieuwe omgeving:
- De branch erft de code en infrastructuur van de huidige Git branch (
sessions-in-redis
); - De gegevens komen uit de master- (aka-productie) omgeving door het maken van een consistente snapshot van alle service-gegevens, inclusief bestanden (bijvoorbeeld door de gebruiker geüploade bestanden) en databases;
- Er wordt een nieuw dedicated cluster gecreëerd om de code, de gegevens en de infrastructuur te deployen.
Aangezien de deployment dezelfde stappen volgt als de deployment naar productie, zullen ook databasemigraties worden uitgevoerd. Dit is een goede manier om te valideren dat de migraties werken met de productiedataset.
De niet-master
omgevingen lijken erg op de master
omgeving, op enkele kleine verschillen na: e-mails worden bijvoorbeeld standaard niet verstuurd.
Zodra de deployment is voltooid, open je de nieuwe branch in een browser:
1 | $ symfony open:remote
|
Merk op dat alle SymfonyCloud commando’s werken op de huidige Git branch. Dit commando opent de deployede URL voor de sessions-in-redis
branch; de URL ziet er dan als volgt uit https://sessions-in-redis-xxx.eu.s5y.io/
.
Test de website op deze nieuwe omgeving, je zou alle gegevens moeten zien die je in de master-omgeving hebt aangemaakt.
Als je meer conferenties aan de master
omgeving toevoegt, dan zullen ze niet in de sessions-in-redis
omgeving verschijnen en vice versa. De omgevingen zijn onafhankelijk en geïsoleerd.
Als de code op master evolueert, kun je altijd de Git branch rebasen en de bijgewerkte versie deployen, waardoor de conflicten voor zowel de code als de infrastructuur worden opgelost.
Je kan zelfs de gegevens van de master terug naar de sessions-in-redis
omgeving synchroniseren:
1 | $ symfony env:sync
|
Het debuggen van productie-deployment vóór de ingebruikname¶
Standaard gebruiken alle SymfonyCloud-omgevingen dezelfde instellingen als de master
/ prod
omgeving (ook wel de Symfony prod
omgeving genoemd). Dit stelt je in staat om de toepassing in reële omstandigheden te testen. Het geeft je het gevoel dat je direct op productieservers ontwikkelt en test, maar zonder de risico’s die daarmee gepaard gaan. Dit doet me denken aan de goede oude tijd toen we deployments via FTP verzorgden.
In het geval van een probleem, kan je misschien overstappen naar de Symfony dev
omgeving:
1 | $ symfony env:debug
|
Als je klaar bent, ga dan terug naar de productie-instellingen:
1 | $ symfony env:debug --off
|
Waarschuwing
Schakel nooit de dev
omgeving of de Symfony Profiler in op de master
branch; het maakt de applicatie traag en zorgt voor een hoop serieuze kwetsbaarheden.
Testen van de productie-deployments voor de ingebruikname¶
Toegang hebben tot de nieuwe versie van de website met productiegegevens biedt veel mogelijkheden: van visuele regressietests tot performance tests. Blackfire is de perfecte tool voor de klus.
Raadpleeg de stap over “Prestaties” om meer te weten te komen over hoe je Blackfire kan gebruiken om jouw code te testen voordat je deze deployt.
Mergen naar productie¶
Als je tevreden bent met de wijzigingen in de branch, merge dan de code en de infrastructuur naar de Git master branch:
1 2 | $ git checkout master
$ git merge sessions-in-redis
|
En deploy:
1 | $ symfony deploy
|
Bij de deployment worden enkel de code en wijzigingen in de infrastructuur naar SymfonyCloud gepusht; de data wordt op geen enkele wijze beïnvloed.
Opruimen¶
Ruim tot slot op door de Git branch en de SymfonyCloud omgeving te verwijderen:
1 2 | $ git branch -d sessions-in-redis
$ symfony env:delete --env=sessions-in-redis --no-interaction
|
- « Previous Stap 10: De gebruikersinterface bouwen
- Next » Stap 12: Luisteren naar events
This work, including the code samples, is licensed under a Creative Commons BY-NC-SA 4.0 license.