Меня зовут Илья Куликов, я руковожу разработкой веб-терминалов в компании «Столото». Сегодня хочу рассказать, как мы превратили ручные релизы и вечные конфликты в почти автономный CI/CD. За почти 10 лет в компании я прошёл путь от бэкенд-разработчика до руководителя направления, в «Столото» же за это время родился и вырос целый продукт — веб-терминал для агентов розничной сети. Изначально у нас был парк дорогих аппаратных терминалов, установленных у агентов. Но как расширить сеть и снизить входной порог? Возникла идея: а что, если сделать аналогичное приложение в браузере? Тогда любой желающий мог бы стать агентом — достаточно старого ноутбука и договора с нами. Так появился полноценный веб-аналог аппаратного терминала со всеми необходимыми функциями для продажи лотерей.

Но вместе с ростом продукта росла и боль: релизы занимали часы, всё постоянно ломалось на проде, а после каждого деплоя команда судорожно грепала логи в поисках причины падения. Мы поняли: без серьёзной перестройки процессов дальше — только хуже. И тогда решили кардинально пересмотреть наш подход к CI/CD. Отказались от классического GitFlow в пользу trunk-based development, полностью перестроили пайплайны в GitLab и внедрили автоматизацию на всех этапах — от сборки и тестирования до деплоя и мониторинга.

О масштабе и требованиях

«Столото» входит в топ-10 мировых лидеров по онлайн-продажам. Около 80% билетов продаётся через цифровые каналы. На платформе ежедневно проходят сотни тиражей, а выплаты — это сотни тысяч операций в день.

Наш IT-ландшафт сравним по требованиям с банками: высокая нагрузка, строгие требования к надёжности и мониторингу. За веб-терминалами стоит команда из десятка человек и несколько десятков инженеров IT-дирекции, обслуживающих этот и многие другие информационные системы компании.

Начну с того, как выглядят наши веб-терминалы.

Веб-терминалы "Столото"
Веб-терминалы "Столото"

Технологический стек: баланс между скоростью, надёжностью и поддержкой

В основе любого современного продукта — продуманный технологический стек, и наш не исключение. Мы сознательно выбрали инструменты, которые позволяют быстро развивать функциональность, обеспечивать стабильность и при этом не упираться в узкие места инфраструктуры.

Фронтенд — на React.js. Это не просто «по привычке», а следование мировому стандарту: React используют и в Meta, и в Netflix, и в Uber. Компонентная архитектура, мощная экосистема и виртуальный DOM дают нам то, что нужно веб-терминалу — мгновенный отклик интерфейса без перезагрузки страницы. Агент не должен ждать: он продаёт билеты, оформляет выигрыши — и всё должно работать «в моменте».

БэкендJava + Spring Boot. Этот стек остаётся одним из самых популярных в корпоративной разработке — и не зря. Он отлично подходит для сложных бизнес-процессов и интеграций. Особенно выручает Spring State Machine — мы моделируем в нём сложные сценарии, вроде цепочек продаж и выплат, как конечные автоматы. Это повышает предсказуемость, а логику делает прозрачной и управляемой.

База данныхMariaDB. Она демонстрирует стабильную производительность и подходит для наших сценариев. Мы держим её за пределами Kubernetes, на выделённых виртуалках: так проще управлять репликацией и бэкапами. (В команде шутим, что Maria в переводе — «горькая отвергающая»: видимо, кластер Kubernetes ей действительно не по душе ?).

Кэш и сессииRedis Sentinel. Он обеспечивает высокую доступность и быстрый отклик. Redis у нас хранит не только сессии, но и контексты состояний из Spring State Machine, чтобы разгрузить память приложений и ускорить восстановление после рестартов.

Всё это работает в контейнерах под управлением Kubernetes. Он стал нашей основной платформой — автоматизирует деплой, масштабирование, обновления, следит за отказоустойчивостью.

Такой стек — это не просто набор «хайповых» технологий, а осознанный выбор в духе мировых трендов: Kubernetes + React + Spring Boot + Redis — комбинация, на которой строят свои продукты Airbnb, Spotify, Alibaba. Это проверенные временем технологии, за которыми стоят большие сообщества, документация и стабильные обновления. А для нас это значит: меньше сюрпризов, больше уверенности в завтрашнем дне.

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

Что нас сподвигло уйти с GitFlow на TBD и что нам это дало

Изначально разработка веб-терминалов велась по классическому GitFlow. Это выглядело логично: master — стабильная ветка, develop — интеграционная, feature-ветки для отдельных задач. Но после нескольких месяцев активной работы мы поняли, что переборщили с GitFlow.

Причины:

  • Feature-ветки жили по 2–3 недели из-за сложной бизнес-логики (например, state machine), и за это время develop сильно продвигался вперёд.

  • При мерже возникали массивные конфликты, которые приходилось разруливать часами.

  • Время на интеграцию росло, а не падало: вместо выпуска фич мы тратили дни на согласование изменений, ручные тесты и разруливание веток.

  • Когнитивная нагрузка на команду была высокой: каждый должен был помнить, в какую ветку коммитить, когда создавать релиз, как правильно делать hotfix.

  • Обратная связь по качеству кода задерживалась: ошибки выявлялись слишком поздно, иногда уже на проде.

Итог: мерджи и конфликты при них прилично тормозили процесс разработки и начало тестирования, вылезали ошибки, а команда теряла скорость. Стало понятно, что нужна другая модель, где интеграция — норма, а не событие, и каждое изменение проверяется максимально рано.

Переход на trunk-based development (TBD)

Мы приняли TBD как единственный рабочий подход: вся команда интегрирует изменения напрямую в master, а feature-ветки существуют только несколько часов или максимум один рабочий день. Это позволило нам:

  • Сократить время интеграции и снизить риск конфликтов.

  • Обеспечить раннее выявление ошибок через непрерывные автотесты.

  • Использовать feature toggles: незавершённые фичи можно сливать в мастер, не включая их для пользователей.

Ключевые требования для успешного TBD:

  • Строгий контроль качества кода: каждый коммит должен проходить юнит- и интеграционные тесты.

  • Обязательные feature toggles, чтобы изменения могли безопасно попадать в мастер.

  • Культура мелких коммитов: проще тестировать, ревьюить и при необходимости откатывать.

TBD стал для нас не просто стратегией ветвления, а основой безопасного, предсказуемого CI/CD, где мастер всегда готов к релизу и каждый коммит проверяется автоматически.

Культура качества и «малые» коммиты

В TBD мастер — это всегда потенциальный продакшен-кандидат. Для нас это значит, что каждый коммит проходит строгий контроль качества:

  • Автоматические тесты: юнит-тесты проверяют базовую логику, интеграционные — взаимодействие с внутренними процессинговыми системами (биллинг, расчёты выигрышей, state machine), а end-to-end и headless UI-тесты проверяют пользовательский поток.

  • Feature toggles позволяют мержить изменения без риска для пользователей.

  • Малые коммиты делают процесс ревью, тестирования и откатов проще и безопаснее.

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

Таким образом, CI/CD-пайплайны и стандарты работы превращают процесс интеграции в предсказуемый, безопасный и быстрый цикл, где мастер остаётся всегда «зелёным».

Почему GitLab и как мы его используем

Для успешного TBD нужна мощная автоматизация: без неё контролировать качество и стабильность мастер-ветки невозможно. Мы выбрали GitLab, развернутый внутри компании, чтобы иметь полный контроль над пайплайнами, merge request’ами и интеграцией с внутренними сервисами.

Переход на Enterprise Edition не произошёл сразу. Сначала мы провели пилот на Community Edition, изучили ключевые функции, оценили возможности автотестов, MR-робота и интеграции с другими системами. Только убедившись, что GitLab решает все необходимые задачи, мы перешли на EE.

Ключевые возможности GitLab, которые мы используем:

  • Единое хранилище кода и пайплайнов (.gitlab-ci.yml рядом с кодом для версионирования и аудита).

  • Автоматический запуск пайплайнов для каждого merge request, отображение статуса тестов и блокировка мержей при провале.

  • Code Owners: автоматическое назначение ревьюеров по ownership-правилам в монорепозитории.

  • Автоматическое масштабирование CI-раннеров: GitLab динамически запускает дополнительные runner’ы в кластере при пике нагрузки и освобождает ресурсы при отсутствии таковой.

MR Robot и интеграция с Atlassian системами и SonarQube

Название MR Robot произошло не просто так — это сокращение от Merge Request, а в шутку мы зовём его «мистер робот». MR Robot управляет merge request’ами, проверяет качество кода и отправляет уведомления. Он работает в пайплайне GitLab через Docker-образ и выполняет:

  • Назначение ревьюеров на основе ownership-правил.

  • Проверку покрытия кода тестами через SonarQube и контроль статического анализа.

  • Обновление статусов в Jira и отправку уведомлений в Telegram о сбоях сборки или блокировке мержей.

  • Интеграция с Confluence позволяет автоматически генерировать документацию для текущей версии продукта: документ по API, паспорт релиза и список задач, вошедших в релиз.

Интеграция с Jira синхронизирует статус задач с кодом: при создании MR задача автоматически переходит в статус «Review», после слияния — закрывается. Это упрощает жизнь команде и ускоряет коммуникацию между менеджерами, разработчиками и QA.

Уровни покрытия кода тестами контролируются жёстко: мы постепенно повышали минимальный порог от 20–30% до 93% для бэкенда и 86% для фронтенда. Это именно покрытие функциональности модулей тестами, а не просто количество строк кода.

Часть функциональности MR Robot доступна в GitLab Enterprise Edition, но мы начинали с Community Edition и добились стабильного процесса даже без EE.

Стратификация пайплайнов

Мы построили многоуровневую систему пайплайнов, где каждый последующий тип проверки дополняет предыдущий:

  • Feature-ветки (краткосрочные) — выполняются при каждом пуше в ветку, запускают сборку и юнит-тесты. Быстро дают обратную связь о базовой работоспособности изменений.

  • Merge Request — дополняют предыдущий уровень: кроме сборки и юнит-тестов запускается статический анализ через SonarQube и интеграционные тесты. MR Robot оценивает, можно ли сливать изменения в мастер.

  • Master-ветка — каждый коммит проходит полный цикл: сборка, юнит- и интеграционные тесты, headless UI-тесты, автотесты бизнес-логики и развертывание на тестовой среде. Если пайплайн прошёл — версия готова к релизу.

  • Релизные ветки — для финальной проверки перед продакшеном дополнительно прогоняются нагрузочные тесты и интеграция со смежными системами на нагрузочном и регрессионном стендах, соответственно.

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

GitOps и Argo CD — стенды под рукой

Для безопасного и предсказуемого деплоя мы внедрили GitOps-подход с использованием Argo CD, развернутого в Kubernetes. Он стал логичным выбором на фоне уже используемого GitLab и K8s: теперь вся конфигурация кластеров хранится в Git, а Argo CD автоматически синхронизирует её с реальным состоянием. Любые ручные изменения кластера возвращаются к «каноническому» состоянию, исключая дрейф конфигураций.

Мы выстроили несколько тестовых стендов, каждый с конкретной задачей:

  • Dev — разворачивается после успешного пайплайна в MR, используется для автоматических тестов и первичной функциональной проверки.

  • TIFA (стенд интеграционного тестирования) — основной для ручного тестирования QA, где проверяются интеграция со смежными системами и регрессионные сценарии.

  • TLI (стенд нагрузочного тестирования) — имитирует характеристики продакшена, проверяет пиковые нагрузки и устойчивость системы.

Ручное тестирование остаётся обязательным этапом — автотесты помогают, но не заменяют человека. Такой подход позволяет команде мгновенно получать изолированные среды, проверять изменения и быстро получать обратную связь.

Доставка в продакшен: канареечные релизы и фич-флаги

Когда каждое изменение может попасть в продакшен за час, важно минимизировать риски. Для этого мы используем канареечный подход: новая версия приложения выкатывается параллельно со старой, а трафик сначала направляется на пилотную группу — ограниченный состав пользователей для проверки продукта. Мы можем управлять составом и количеством участников пилота, а также последовательностью и долей трафика, которую они получают.

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

Для управления функциональностью мы используем Unleash — систему feature toggles. С её помощью можно мержить незавершённые функции в мастер, но держать их выключенными для пользователей до полной готовности. Unleash позволяет комбинировать разные версии приложения и разную функциональность одной и той же версии между пилотной и основной группами, что особенно ценно для сложных бизнес-процессов и экспериментов с новыми подходами.

В итоге канареечные релизы и feature flags дают нам гибкость: новые функции тестируются аккуратно, контроль над рисками сохраняется, а пользователи не сталкиваются с неожиданными сбоями.

Техдолг и забота о качестве

Даже самая продвинутая инфраструктура не защищает от накопления технического долга. Если его игнорировать, продукт начинает деградировать: код становится трудночитаемым, новые фичи вводятся медленно, а ошибки чаще проявляются на продакшене. Известные примеры — старые версии Facebook или Twitter в первые годы, когда масштаб и скорость роста вынуждали жертвовать качеством кода: без регулярного рефакторинга они сталкивались с падением производительности и ростом багов.

Поэтому мы сознательно выделяем 25–30% времени спринта на устранение техдолга: рефакторинг, переработку архитектуры, обновление библиотек и фреймворков до последних стабильных версий. Это позволяет нам:

  • Поддерживать код читаемым и поддерживаемым.

  • Обеспечивать совместимость и безопасность. Новые версии фреймворков и библиотек часто закрывают уязвимости и баги, а старые — наоборот создают риски.

  • Сохранять скорость внедрения новых функций: чистая архитектура и актуальные зависимости делают разработку предсказуемой.

Рефакторинг помогает не просто «чистить код», а улучшать архитектуру и логику взаимодействия компонентов. Например, мы перерабатываем сложные модули Spring State Machine, оптимизируем работу с Redis и пересматриваем структуру фронтенд-компонентов. Это снижает количество ошибок, ускоряет тестирование и делает систему более гибкой при изменении бизнес-требований.

Использование последних версий библиотек и фреймворков — обязательное правило для нашей команды. Оно помогает нам избегать технических ловушек прошлого и оставаться на передовой, как делают крупнейшие ИТ-компании: Spotify, Netflix и Airbnb регулярно инвестируют в обновления и рефакторинг, чтобы сохранять скорость и стабильность продукта при росте нагрузки и функциональности.

Как мы работаем с задачами

Наш день с новым подходом:

  • Продукт-менеджер формулирует задачу и создаёт её в Jira. Она сразу попадает в список для разработки.

  • Разработчик берёт задачу, создаёт feature-ветку, делает небольшие коммиты, пишет юнит-тесты и интеграционные тесты. После этого создаёт Merge Request.

  • MR Robot автоматически проверяет код: назначает ревьюеров, запускает статический анализ через SonarQube, проверяет покрытие тестами и уведомляет команду о статусе сборки.

  • Ревьюеры смотрят MR — фронтендеры проверяют интерфейс, бэкендеры — бизнес-логику и интеграцию с state machine. MR не сливается, пока все проверки и ревью не пройдены.

  • QA-инженер получает развёрнутый на стенде Dev билд, запускает ручное тестирование и проверяет сценарии, которые сложно покрыть автотестами. Автотесты здесь — помощники, ускоряющие работу, но не заменяющие человека.

  • После одобрения MR код сливается в master, где запускается полный цикл пайплайнов: сборка, все тесты, headless UI и интеграция с внутренними сервисами.

  • Технический лидер и продукт-менеджер наблюдают за результатами на стендах TIFA и TLI, проводят финальную проверку и принимают решение о релизе.

  • Деплой идёт через канареечные релизы с фич-флагами, где пилотная группа пользователей проверяет новые функции. При успехе изменения доходят до всей аудитории.

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

Заключение и советы для тех, кто на старте

Наш путь от ручных релизов и вечных конфликтов в GitFlow к стабильному, почти «невидимому» CI/CD занял время, но результат того стоил. Мы не просто ускорили доставку кода — мы изменили культуру разработки: теперь команда не боится мержить в пятницу вечером, а продакшен перестал быть «зоной риска».

Ключевые выводы в формате утверждений и вопросов к вам:

  • Автоматизация и CI/CD работают: вы можете уменьшить ручную рутину и ускорить поставку фич. А вы используете инструменты автоматизации на полную мощность в своей команде?

  • Культура качества решает всё: мелкие коммиты, тесты и фич-флаги делают мастер надёжным. А как вы поддерживаете стабильность своего кода при быстром развитии продукта?

  • Техдолг требует внимания: регулярный рефакторинг и обновление библиотек сохраняют гибкость и скорость. Вы выделяете время на системное улучшение кода или гасите пожары по мере их появления?

  • Постепенная проверка изменений снижает риски: канареечные релизы и пилотные группы позволяют аккуратно тестировать новые функции. А у вас есть безопасный способ проверять изменения перед полной выкладкой?

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

Комментарии (2)


  1. iamkisly
    27.10.2025 14:01

    Тю, я думал будет пост про сравнительно законный способ объёма денег у населения)


  1. motoronik
    27.10.2025 14:01

    Такое ощущение что базовый флоу релиза, с тестами (юниты, интеграционные), линтерами, анализаторами и прочим ci/cd сахаром вы преподносите как некую новеллу ;)

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