Шаг 11: Работа с ветками

5.0 version
Maintained

Работа с ветками

Существует множество способов организации работы с кодом в проекте. Однако фиксировать изменения непосредственно в master-ветке Git и напрямую развёртывать код в продакшен без тестирования, пожалуй, не лучший вариант.

Тестирование — это не только модульные или функциональные тесты, но и проверка поведения приложения с использованием реальных данных. Если вы или ваши заинтересованные стороны можете просмотреть приложение в том самом виде, в котором оно предстанет перед конечными пользователями, это становится огромным преимуществом и позволяет вам развёртывать приложения с уверенностью. Особенно полезно, когда нетехнические специалисты могут проверять новую функциональность.

Для упрощения и чтобы избежать повторения на следующих шагах мы продолжим работу в master-ветке Git, однако давайте посмотрим, как это можно организовать получше.

Организация рабочего процесса с помощью Git

Создание отдельной ветки на каждую новую функциональность или исправление бага — один из простых и эффективных вариантов организации рабочего процесса.

Описание инфраструктуры

Возможно, вы пока ещё не осознали это, но хранение инфраструктурных файлов рядом с кодом, очень удобно. Docker и SymfonyCloud используют конфигурационные файлы для описания инфраструктуры проекта. Когда для работы новой функциональности необходим дополнительный сервис, изменения в коде и инфраструктуре находятся в одном патче.

Создание веток

Рабочий процесс начинается с создания ветки в Git:

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

Команда из примера создаёт ветку sessions-in-redis из ветки master. Это действие создаёт ответвление кода и конфигурации инфраструктуры.

Хранение сессий в Redis

Вероятно, вы уже поняли из названия ветки, что для хранения сессий вместо файловой системы мы будем использовать хранилище в Redis.

Необходимые шаги для реализации этого вполне типичны:

  1. Создайте новую ветку в Git;
  2. Обновите конфигурацию Symfony, если потребуется;
  3. При необходимости напишите и/или обновите код;
  4. Обновите конфигурацию PHP, добавив PHP-модуль Redis;
  5. Обновите инфраструктуру Docker и SymfonyCloud, добавив сервис Redis;
  6. Протестируйте локально;
  7. Протестируйте удалённо;
  8. Выполните слияние ветки с основной веткой;
  9. Разверните в продакшене;
  10. Удалите ветку.

Все изменения, выполненные с 2 по 5 шаг, можно применить одним патчем:

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]

Разве это не замечательно?

«Перезагрузите» Docker, чтобы запустить сервис Redis:

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

Протестируйте сайт на своём компьютере, просматривая различные страницы. Поскольку мы не вносили никаких визуальных изменений и пока не используем сессии, всё должно работать как и раньше.

Развёртывание ветки

Перед развёртыванием в продакшене, мы должны протестировать ветку в окружении ему идентичному. Нам необходимо убедиться, что всё работает корректно в Symfony-окружении prod (локальный сайт использует окружение dev).

Для начала зафиксируйте изменения в новой ветке:

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

Теперь давайте создадим SymfonyCloud-окружение на основе Git-ветки:

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

Данная команда создаёт новое окружение в следующем порядке:

  • Ветка наследует код и инфраструктуру от текущей Git ветки (sessions-in-redis);
  • Данные поступают из основного окружения (т.е. продакшена) путём создания последовательных слепков всех служебных данных, включая файлы (например, загруженные пользователями) и базы данных;
  • Создаётся новый выделенный кластер для развёртывания кода, данных и инфраструктуры.

Поскольку развёртывание проходит те же этапы, что и развёртывание в продакшене, миграции базы данных также будут выполнены. Это отличный способ проверить, что миграции работают с данными в продакшене.

Окружения, отличные от master, на самом деле очень на него похожи, но есть небольшие отличия. Например, отправка электронных писем отключена по умолчанию.

После завершения развёртывания откройте новую ветку в браузере:

1
$ symfony open:remote

Обратите внимание, что все команды SymfonyCloud работают в текущей Git-ветке. Выполненная выше команда откроет URL-адрес для только что развёрнутой ветки sessions-in-redis. Адрес будет выглядеть примерно так: https://sessions-in-redis-xxx.eu.s5y.io/.

Протестируйте сайт в новом окружении: вы увидите те же данные, что и в основном окружении.

Если добавить новые конференции в основное окружение (master), они не появятся в окружении sessions-in-redis и наоборот, так как окружения являются независимыми и полностью изолированными друг от друга.

Если код изменится в основной ветке, вы всегда можете выполнить перебазирование Git-ветки и развернуть обновлённую версию, разрешив конфликты в коде и инфраструктуре.

В том числе вы можете синхронизировать данные с основного окружения в окружение sessions-in-redis:

1
$ symfony env:sync

Предварительная отладка развёртывания в продакшене

По умолчанию все SymfonyCloud-окружения используют те же настройки, что и окружение master/prod (то же, что и окружение prod в Symfony). Это позволяет протестировать приложение в реальных условиях (как и в продакшене). Таким образом создаётся ощущение разработки и тестирования непосредственно на продакшен-серверах, но без связанных с этим рисков. Мне напоминает это старые добрые времена, когда мы развёртывали проекты через FTP.

При возникновении проблемы вы можете переключиться на Symfony-окружение dev:

1
$ symfony env:debug

Как только закончите, переключитесь обратно к продакшен-настройкам:

1
$ symfony env:debug --off

Предупреждение

Никогда не активируйте окружение dev и никогда не используйте профилировщик Symfony, находясь в ветке master, это приведёт к тому, что ваше приложение станет очень медленным и откроет множество серьёзных дыр безопасности.

Предварительное тестирование развёртывания в продакшене

Возможность предварительного просмотра будущей версии сайта с продакшен-данными открывает широкие возможности: от визуального регрессионного тестирования до тестирования производительности. Blackfire — идеальный инструмент для такого рода задач.

Перейдите к шагу «Производительность», чтобы узнать больше про использование Blackfire для тестирования кода перед развёртыванием.

Развёртывание в продакшене

Если вы полностью удовлетворены изменениями в ветке с новой функциональностью, выполните слияние кода и инфраструктуры в master-ветку в Git:

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

И разверните:

1
$ symfony deploy

При развёртывании в SymfonyCloud отправляются только изменения в коде и инфраструктуре; данные останутся такими же, как и были до развёртывания.

Очистка

В завершение выполните очистку, удалив Git-ветку и SymfonyCloud-окружение:

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

  • « Previous Шаг 10: Создание пользовательского интерфейса
  • Next » Шаг 12: Обработка событий

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