Перейти к основному содержимому

Как начать работать со стратегиями ветвления в git и dbt

· 29 мин. чтения
Christine Berger
Resident Architect at dbt Labs
Carol Ohms
Resident Architect at dbt Labs
Taylor Dunlap
Senior Solutions Architect at dbt Labs
Steve Dowling
Senior Solutions Architect at dbt Labs

Привет! Мы — Кристин и Кэрол, Resident Architects в dbt Labs. Наша повседневная работа связана с тем, чтобы помогать командам достигать как технических, так и бизнес-ориентированных целей. Работая с самым разным кругом клиентов — от небольших стартапов до крупных корпораций — мы накопили ценный опыт в сопровождении команд при внедрении архитектуры, которая решает их ключевые болевые точки.

Информация, которой мы собираемся поделиться, основана не только на нашем опыте — мы регулярно сотрудничаем с другими экспертами, такими как Taylor Dunlap и Steve Dowling, которые внесли значительный вклад в формирование этих рекомендаций. Их работа заключается в том, чтобы быть критически важным мостом для команд между реализацией и бизнес-результатами, в конечном итоге помогая выработать целостное техническое видение через выявление проблем и решений.

Зачем мы здесь?
Мы помогаем командам с архитектурой dbt, которая включает в себя инструменты, процессы и конфигурации, используемые для начала разработки и деплоя с dbt. За кулисами происходит множество решений, направленных на стандартизацию этих составляющих — и во многом они определяются тем, каким мы хотим видеть процесс разработки. Стремление к идеальному workflow часто приводит к тому, что команды застревают в бесконечном планировании и обсуждениях, что замедляет или даже полностью останавливает разработку. Если вам это знакомо, мы надеемся, что наши рекомендации помогут вам чувствовать себя увереннее и начать разблокировать разработку — даже если пока не всё до конца продумано!

Есть три основных инструмента, которые играют ключевую роль в разработке с dbt:

  • Репозиторий
    Содержит код, который мы хотим изменить или задеплоить, а также инструменты для управления процессами изменений.
  • Платформа данных
    Содержит данные для входных источников (загружаемые из других систем), а также базы данных и схемы для выходных данных, плюс управление правами доступа к объектам.
  • Проект dbt
    Помогает управлять процессами разработки и деплоя нашего кода на платформу данных (и делает ещё много полезных вещей!)
отношения dbt с Git и платформой данныхотношения dbt с Git и платформой данных

Независимо от того, как именно вы определяете workflow разработки, следующие ключевые этапы присутствуют всегда:

  • Development: как команда вносит и тестирует изменения в код
  • Quality Assurance: как команда убеждается, что изменения работают корректно и дают ожидаемый результат
  • Promotion: как изменения продвигаются на следующий этап
  • Deployment: как изменения становятся доступными для других

В этой статье мы в основном сосредоточимся на git и репозитории, на том, как код соотносится с заполнением платформы данных, а также на типичных конфигурациях dbt, которые мы используем для этого. По ходу статьи мы будем постоянно привязываться к этапам workflow разработки.

Почему стоит сосредоточиться на git

Контроль версий (и git в частности) является фундаментом современной разработки — как с dbt, так и без него. Он упрощает совместную работу команд любого размера и позволяет легко отслеживать изменения кода в проекте. Понимание этих управляемых процессов и того, как выглядит код на каждом этапе, значительно упрощает понимание того, как нам нужно настраивать платформу данных и dbt.

⭐️ Как «просто начать» ⭐️

В этой статье мы довольно глубоко разбираем темы, связанные с git — это будет полезно, если ваша команда уже знакома с некоторыми вариантами и хочет лучше разобраться в компромиссах. Если же вы только начинаете и у вас нет чётких предпочтений, мы рекомендуем начать с Direct Promotion.

Direct Promotion — это основа всех стратегий ветвления в git. Она хорошо работает при базовом знании git, требует минимальных настроек и легко эволюционирует в другую стратегию, если и когда это потребуется вашей команде. Мы понимаем, что такая рекомендация может вызывать мысли в духе «а что если?». Мы предлагаем думать о начале с direct promotion как о пошиве костюма. Разработчики могут носить его, пока вы разбираетесь с подгонкой, и это гораздо более информативный шаг вперёд, потому что позволяет увидеть, как костюм работает в движении — а итоговые корректировки могут сильно отличаться от тех, которые казались нужными, когда он был статичен.

Лучшее в подходе «просто начать» — это то, что позже изменить конфигурации dbt под другую git-стратегию совсем несложно (и мы это рассмотрим), поэтому не стоит воспринимать это как критическое решение, которое приведёт к месяцам поломанной разработки из‑за перенастройки, если вы сразу выберете неидеальный вариант. На самом деле смена git-стратегии в dbt Cloud может занять всего несколько минут.

Стратегии ветвления

После первого коммита в репозитории всегда есть одна основная ветка по умолчанию, которая обычно называется main или master — в дальнейших примерах мы будем использовать main. Ветка main всегда является конечной точкой, куда мы стремимся доставить изменения, и чаще всего соответствует понятию «production» — этот термин вы тоже будете видеть дальше.

Главный вопрос — как мы хотим выстроить процесс доставки изменений от разработки до main. Этот процесс должен учитывать все этапы workflow: development, quality assurance, promotion и deployment. Стратегии ветвления определяют, как именно выглядит этот процесс. В dbt мы не изобретаем велосипед — существует множество общепринятых стратегий, которые были описаны, реализованы, доработаны и протестированы как минимум за последнее десятилетие.

Существует две основные стратегии, которые охватывают все варианты ветвления: Direct Promotion и Indirect Promotion. Начнём с их общего описания:

  • Что это за стратегия?
  • Как workflow разработки выглядит для команды?
  • Какие правила ветвления и вспомогательные механизмы репозитория используются?
  • Как обычно настраивается dbt Cloud для этой стратегии?
  • Как ветки и процессы dbt сопоставляются с платформой данных?

В конце мы сравним стратегии и ответим на часто задаваемые вопросы.

Прежде чем начнем

Существует множество способов настроить каждый инструмент (особенно dbt) под ваши задачи. Описания стратегий ниже намеренно сфокусированы на том, что мы считаем минимальным стандартом, позволяющим быстро запустить команды в работу. Это стартовые конфигурации и практики, которые легко изменить и доработать позже. Расширение этих настроек мы оставляем на усмотрение читателя!

Прямое продвижение (Direct promotion)

Direct promotion означает, что в репозитории есть только одна долгоживущая ветка — в нашем случае main. Вот как выглядит workflow для этой стратегии:

Стратегия ветвления Direct promotionСтратегия ветвления Direct promotion

Как выглядит workflow разработки для команды?

Структура:

  • feature — индивидуальная ветка разработчика, где выполняются изменения по задаче
  • main — ветка с «production»-версией кода

Workflow:

  • Development: я создаю ветку feature от main, чтобы вносить изменения, тестировать их и проводить первичную самопроверку
  • Quality Assurance: я открываю pull request, сравнивающий feature с main, который затем проходит ревью у коллег (обязательно), стейкхолдеров или предметных экспертов (SME). В этой стратегии мы настоятельно рекомендуем привлекать стейкхолдеров или SME к PR, потому что следующий шаг меняет main.
  • Promotion: после всех необходимых одобрений и проверок я мержу изменения в main
  • Deployment: после мержа и деплоя main другие могут видеть и использовать мои изменения

Правила ветвления и вспомогательные механизмы репозитория

Как минимум мы рекомендуем настроить:

Процессы и окружения dbt Cloud

Вот та же стратегия ветвления, но уже с процессами dbt Cloud, которые мы хотим использовать:

Стратегия Direct Promotion с обозначенными процессами dbt CloudСтратегия Direct Promotion с обозначенными процессами dbt Cloud

Чтобы создать jobs из диаграммы, нам нужны окружения dbt Cloud. Типовые конфигурации для этого сценария выглядят так:

Название окруженияТип окруженияТип развертыванияБазовая веткаОбработчик
Developmentdevelopment-mainОперации в IDE (включая создание feature-веток)
Continuous IntegrationdeploymentGeneralmainCI job
ProductiondeploymentProductionmainDeployment job
Loading table...

Организация платформы данных

Теперь нужно определить, где именно мы будем создавать объекты на платформе данных. Для этого настраиваются параметры database и schema в окружениях. Вот та же диаграмма, но с отображением того, как объекты из веток попадают на платформу данных:

Стратегия Direct Promotion со связями веток с объектами платформы данныхСтратегия Direct Promotion со связями веток с объектами платформы данных

Дополним ранее созданную таблицу окружений dbt Cloud сопоставлением с платформой данных:

Название окруженияБаза данныхСхема
DevelopmentdevelopmentЗадаётся пользователем в Profile Settings > Credentials
Continuous IntegrationdevelopmentЛюбое безопасное значение, например dev_ci (даже не обязательно, чтобы схема существовала). Job всё равно переопределит схему под конкретный PR.
Productionproductionanalytics
Loading table...
примечание

Здесь показаны конфигурации окружений, однако база данных по умолчанию задаётся на более высоком уровне — в connection (это обязательная настройка окружения). Deployment-окружения при необходимости могут переопределять database из connection.

Пример direct promotion

В этом примере Steve использует термин “QA” для обозначения окружения, которое собирает изменённый код из pull request’ов feature-веток. Это эквивалент нашего окружения “Continuous Integration” — отличный пример того, как можно выбирать названия, наиболее понятные вашей команде!

Косвенное продвижение (Indirect Promotion)

Заметка о косвенном продвижении (Indirect Promotion)

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

Косвенное продвижение добавляет другие долгоживущие ветки, которые производятся от main. Самая простая версия косвенного продвижения — иерархическая структура с двумя «стволами» — именно её мы чаще всего видим реализованной в косвенных рабочих процессах.

Иерархическое продвижение — это продвижение изменений обратно тем же путём, которым мы выводили ветки. Пример:

  • промежуточная ветка создаётся от main
  • feature-ветки создаются от промежуточной ветки
  • feature-ветки сливаются обратно в промежуточную ветку
  • промежуточная ветка сливается обратно в main

Некоторые распространённые названия для промежуточной ветки, которые встречаются на практике:

  • qa: Quality Assurance
  • uat: User Acceptance Testing
  • staging или preprod: распространённая терминология в разработке ПО

В оставшейся части статьи мы будем называть нашу промежуточную ветку qa.

Вот рабочий процесс для этой стратегии:

Indirect Promotion branching strategyIndirect Promotion branching strategy

Как выглядит рабочий процесс разработки глазами разработчика?

Изменения относительно нашего процесса direct promotion подсвечены синим.

Схема:

  • feature — личная ветка разработчика, где происходят изменения по задаче
  • qa содержит одобренные изменения из feature-веток разработчиков; после дополнительного тестирования они будут слиты в main и попадут в продакшен вместе.qa всегда опережает main по изменениям.
  • main — ветка, которая содержит нашу «продакшен»-версию кода

Процесс:

  • Разработка: я создаю ветку feature от qa, чтобы вносить изменения, тестировать их и делать личную проверку
  • Quality Assurance: я открываю pull request, сравнивая мою ветку feature с qa; затем PR просматривают коллеги и при необходимости эксперты по предметной области или стейкхолдеры
  • Продвижение: после всех требуемых согласований и проверок я могу слить свои изменения в qa
  • Quality Assurance: эксперты по предметной области или другие стейкхолдеры могут просмотреть мои изменения в qa, когда я сливаю свой feature
  • Продвижение: когда специалисты QA одобряют версию данных в qa, release manager открывает pull request из ветки qa в main (мы называем это «релизом»)
  • Развёртывание: другие смогут увидеть и использовать мои изменения (и изменения других) в main после того, как qa будет слита в main и main будет развёрнута

Правила ветвления в репозитории и вспомогательные настройки

Как минимум, нам нравится настраивать:

Процессы и окружения dbt Cloud

Вот наша стратегия ветвления ещё раз, но теперь с процессами dbt Cloud, которые мы хотим включить:

Indirect Promotion strategy with dbt cloud processes denotedIndirect Promotion strategy with dbt cloud processes denoted

Чтобы создать джобы на нашей схеме, нам нужны окружения dbt Cloud. Вот типичные конфигурации для такого сетапа:

Название окруженияТип окруженияТип развертыванияБазовая веткаБудет обрабатывать…
Developmentdevelopment-qaОперации, выполняемые в IDE (включая создание feature-веток)
Feature CIdeploymentGeneralqaДжоб непрерывной интеграции
Quality AssurancedeploymentStagingqaДжоб развертывания
Release CIdeploymentGeneralmainДжоб непрерывной интеграции
ProductiondeploymentProductionmainДжоб развертывания
Loading table...

Организация платформы данных

Теперь нужно сфокусироваться на том, где мы хотим собирать объекты в нашей платформе данных. Для этого нам нужно задать настройки database и schema в окружениях. Есть два распространённых варианта сопоставления кода, но прежде чем перейти к ним, вспомним это примечание из direct promotion:

примечание

Здесь мы показываем конфигурации окружений, но база данных по умолчанию задаётся на более высоком уровне — в подключении (а подключение — обязательная настройка окружения). Deployment-окружения при необходимости могут переопределять настройку базы данных из подключения.

  • Конфигурация 1: соответствие 1:1 для ресурсов qa и main В этом паттерне CI-схемы создаются в базе данных вне Production и QA. Обычно так делают, чтобы базы данных соответствовали тому, что слито в их ветки. Вот наша схема, но теперь с сопоставлением на платформу данных для этого паттерна:

    Indirect Promotion branches and how they relate to 1\:1 organization in the data platformIndirect Promotion branches and how they relate to 1\:1 organization in the data platform

    Вот конфигурации для этого паттерна:

    Название окруженияDatabaseSchema
    DevelopmentdevelopmentУказывается пользователем в Profile Settings > Credentials
    Feature CIdevelopmentЛюбое безопасное значение по умолчанию, например dev_ci (оно даже не обязано существовать). Джоб, который мы планируем настроить, всё равно переопределит schema, чтобы обозначить уникальный PR.
    Quality Assuranceqaanalytics
    Release CIdevelopmentБезопасное значение по умолчанию
    Productionproductionanalytics
    Loading table...
  • Конфигурация 2: отражение инициативы рабочего процесса

    В этом паттерне CI-схемы создаются в базе qa, потому что это часть шага quality assurance. Вот наша схема, но теперь с сопоставлением на платформу данных для этого паттерна:

    Indirect Promotion branches and how they relate to workflow initiative organization in the data platformIndirect Promotion branches and how they relate to workflow initiative organization in the data platform

    Вот конфигурации для этого паттерна:

    Название окруженияDatabaseSchema
    DevelopmentdevelopmentУказывается пользователем в Profile Settings > Credentials
    Feature CIqaЛюбое безопасное значение по умолчанию, например dev_ci (оно даже не обязано существовать). Джоб, который мы планируем настроить, всё равно переопределит schema, чтобы обозначить уникальный PR.
    Quality Assuranceqaanalytics
    Release CIqaБезопасное значение по умолчанию
    Productionproductionanalytics
    Loading table...

Пример косвенного продвижения (Indirect Promotion)

В этом примере Стив использует термин «UAT», чтобы обозначить автоматическое развертывание промежуточной ветки, а «QA» — чтобы обозначить то, что собирается из pull request’ов feature-веток. Он также задаёт отдельную базу данных для каждого из них (всего четыре базы: одна для development-схем, одна для CI-схем, одна для развертываний промежуточной ветки и одна для продакшен-развертываний) — мы хотели показать вам этот пример, потому что он демонстрирует, насколько гибко можно настраивать эти процессы вне наших стандартных примеров.

Что изменило косвенное продвижение?

Вы, вероятно, заметили, что общая тема здесь одна — добавление дополнительной ветки, и это про поддержку нашей инициативы Quality Assurance. Разберём по пунктам:

  • Разработка

    Хотя никто не будет разрабатывать прямо в ветке qa, ей всё равно нужен уровень контроля — так же, как он нужен feature-ветке, — чтобы оставаться синхронизированной со своей базовой веткой. Это потому, что изменение в main (например, хотфикс или случайное слияние) теперь не подсветится сразу в наших feature-ветках, ведь они основаны на версии кода из qa. Поэтому эта ветка должна оставаться синхронизированной с любыми изменениями в main.

  • Quality Assurance

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

    • Тестирование и проверка того, как сквозные (end-to-end) изменения работают с течением времени
    • Развертывание полного слепка изменений из qa в централизованное место. Вот несколько типичных причин разворачивать код qa:
      • Использование deferral и функций сравнения Advanced в CI
      • Тестирование сборок на данных, специфичных для окружения (динамические источники)
      • Создание staging-версий воркбуков в вашем BI-инструменте. Это наиболее актуально, когда BI-инструмент плохо справляется с изменением базовых схем. Например, в некоторых инструментах есть хорошие механизмы: взять продакшен-воркбук для разработки, переключить базовую схему на dbt_cloud_pr_#-схему и отразить изменения без поломок. Другие инструменты ломают каждый выбор колонок в воркбуке, даже если структура данных та же. Поэтому иногда проще создать один «staging»-воркбук и всегда указывать ему на базу данных, собранную из QA-кода — тогда изменения можно постоянно отражать и проверять в этом воркбуке, прежде чем изменения кода окажутся в продакшене.
      • Для других людей, которые хотят увидеть или протестировать изменения, но не относятся к ролям, которые участвуют в процессе ревью. Например, эксперт по предметной области может делать ревью и утверждать изменения вместе с разработчиками и понимать процесс просмотра dbt_cloud_pr-схем. Но если этот человек сообщит, что только что одобрил некоторые изменения в разработке, своим коллегам, которые будут эти изменения использовать, команда может спросить, есть ли способ тоже увидеть изменения. Поскольку CI-схема удаляется после merge, им пришлось бы ждать появления изменения в продакшене, если нет процесса, который разворачивает промежуточную ветку.
  • Продвижение

    Теперь есть два места, где нужно продвигать код:

    • Из feature в qa разработчиком и коллегой (и опционально — экспертами по предметной области или стейкхолдерами)
    • Из qa в main release manager’ом и экспертами по предметной области или стейкхолдерами

    Кроме того, одобренные изменения из feature-веток продвигаются вместе из qa.

  • Развертывание

    Теперь есть две основные ветки, из которых можно разворачивать код:

    • qa: «рабочая» версия с изменениями; сюда сливаются feature
    • main: «продакшен» версия

    Поскольку наши изменения накапливаются в ветке qa, процесс развертывания меняется с continuous deployment («потокового» внесения изменений в main в direct promotion) на continuous delivery («пакетного» внесения изменений в main). Джулия Шоттенстайн отлично объясняет различия здесь.

Сравнение стратегий ветвления

Поскольку большинство команд могут работать по direct promotion, перечислим несколько ключевых признаков, когда мы начинаем думать о indirect promotion вместе с командой:

  • Они говорят о выделенном окружении для QA, UAT, staging или pre-production работ.
  • Они спрашивают, как тестировать изменения end-to-end и во времени до того, как они попадут в продакшен.
  • Их разработчики — не те же самые (или не единственные) люди, которые проверяют корректность выходных данных, особенно если другие участники лучше знакомы с валидациями в других инструментах (например, в BI-дашбордах).
  • Их разные окружения не работают с идентичными данными. Как и в софтверных окружениях, у них могут быть ограниченные или «очищенные» версии продакшен-данных в зависимости от окружения.
  • У них есть расписание, когда изменения должны становиться «публичными», и они хотят удерживать фичи от того, чтобы их было видно или можно было использовать, до этого момента.
  • У них очень высокие ставки на потребление данных.

Если вам подходит любой из этих пунктов, скорее всего вам подходит стратегия косвенного продвижения.

Сильные и слабые стороны

Мы настоятельно рекомендуем выбирать стратегию ветвления исходя из того, какая лучше всего поддерживает потребности вашего рабочего процесса, а не из воспринимаемых «плюсов и минусов» — в контексте структуры вашей команды и технических навыков вы увидите, что некоторые вещи вовсе не являются ни сильными, ни слабыми сторонами!

  • Direct promotion

    Сильные стороны

    • Гораздо быстрее с точки зрения того, чтобы увидеть изменения: как только PR слит и задеплоен, изменения уже «в продакшене».
    • Изменения не застревают в промежуточной ветке, ожидая принятия чьей-то валидации выходных данных.
    • Управление в основном распределено: каждый разработчик владеет своей веткой и следит, чтобы она была синхронизирована с тем, что в main.
    • Не нужно думать о релизах, поэтому нет дополнительных процессов управления.

    Слабые стороны

    • Могут возникать сложности с тестированием изменений end-to-end или во времени в окружении, которое не является продакшеном. Наше стремление собирать только изменённые и напрямую затронутые модели, чтобы сократить количество моделей, выполняемых в CI, противоречит идее полного end-to-end тестирования, а наш CI-механизм (который запускается только на pull request или новый коммит) не поможет тестировать во времени.
    • Может быть сложнее с разными графиками или техническими возможностями, когда речь идёт о ревью. В этой стратегии важно подключать стейкхолдеров или экспертов по предметной области к pull request’ам до слияния, потому что следующий шаг — продакшен. Кроме того, некоторые инструменты плохо переключают базы данных и схемы, даже если форма данных одинаковая. Постоянные поломки отчётов ради ревью могут давать слишком большой оверхед.
    • Может быть сложнее тестировать конфигурации или изменения джобов до попадания в продакшен — особенно если поведение немного различается в зависимости от окружения.
    • Может быть сложнее делиться кодом, который полностью работает, но не является полным отражением завершённой задачи. Изменения нужно согласовать, чтобы отправить их в продакшен и чтобы другие могли их подтянуть; иначе разработчикам нужно понимать, как подтягивать это из других веток, не main (и помнить о синхронизации, иначе есть риск конфликтов при слиянии).
  • Indirect promotion

    Сильные стороны

    • Есть выделенное окружение, чтобы тестировать end-to-end изменения во времени.
    • Выходные данные можно проверять либо вместе с разработчиком в PR, либо уже после того, как изменения окажутся в промежуточной ветке.
    • Ревью из других инструментов становится гораздо проще, потому что можно развернуть промежуточную ветку в централизованное место. «Staging»-отчёты можно настроить так, чтобы они всегда ссылались на это место для просмотра изменений, а процессы создания новых отчётов могут идти от staging к production.
    • Конфигурации и изменения джобов можно тестировать с продакшен-подобными параметрами до того, как они реально попадут в продакшен.
    • Изменения, слитые в промежуточную ветку для совместной разработки, не будут отражены в продакшене. Потребители main вообще не будут знать о том, что разработчики делают для удобства сотрудничества.

    Слабые стороны

    • Изменения могут попадать в продакшен медленнее из‑за дополнительных процессов вокруг промежуточной ветки. Чтобы всё двигалось, должен быть человек (или группа), которые полностью отвечают за управление изменениями, статус валидации и релизный цикл.
    • Валидные изменения могут застревать «за» другими изменениями, которые невалидны; крайне важно иметь хороший план, как команда должна действовать в таком сценарии, потому что такая дилемма может задерживать попадание изменений в продакшен.
    • Появляется дополнительное управление новыми «стволами» (trunks), и им нужно владение; без человека (или группы) с достаточными знаниями может быть трудно понять, что нужно делать и как действовать, когда всё выходит из синхронизации.
    • Может потребоваться дополнительный compute в виде запланированных джобов в QA-окружении, а также дополнительный CI-джоб из qa > main для тестирования релизов до их слияния.

Дальнейшие улучшения

Когда базовые конфигурации готовы, вы можете дополнительно настроить проект, подумав, какие ещё функции будут полезны под ваши нужды:

Часто задаваемые вопросы про Git

Общие

Как не дать разработчикам менять определённые файлы?

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

Как запускать другие виды проверок в процессе разработки?

Автоформатирование и линтинг — это функции, доступные в IDE dbt Cloud. Линтинг можно включить в рамках CI job.

Другие виды проверок обычно реализуются через внешние пайплайны — и чаще всего через Git-провайдера, потому что это соответствует тому, где именно такие проверки нужны в процессе разработки. У многих Git-провайдеров есть функциональность пайплайнов, например GitHub Actions или GitLab CI/CD Pipelines. Вот пример, который проверяет, что имя ветки соответствует шаблону при событии pull request).

Как откатывать изменения?

Это действие выполняется вне dbt — через Git-операции, но быстрое решение можно реализовать с помощью git tags/releases, пока вы не исправите код так, как вам нужно:

  • Поставьте git tag (функция есть на большинстве Git-платформ) на commit SHA, к которому вы хотите откатиться
  • Используйте этот tag как custom branch в вашем production-окружении в dbt Cloud. Теперь джобы будут выкачивать код именно на этот момент времени.
  • Дальше можно работать как обычно. Исправляйте через стандартный процесс разработки или попросите знающего человека откатить изменения через Git — неважно: продакшен будет «прибит» к предыдущему состоянию, пока вы не переключите custom branch обратно на main!

Только для indirect promotion

Как делать релизы?

В наших примерах мы отмечали, что под релизом мы понимаем pull request из qa в main, и открывается он из Git-платформы.

Если в pull request исходная ветка — qa, то пока PR открыт, в него также будут подтягиваться новые merge’и в qa, и это может привести к тому, что при merge в main непреднамеренно попадут другие фичи. Поэтому важно, чтобы человек, который открывает релиз, следил за merge’ами и последними запусками, чтобы гарантировать корректность изменений до слияния релиза. Мы обычно используем два подхода, чтобы упростить это:

  • CI job для pull request’ов в main: он запустит CI, сравнивая нашу промежуточную ветку с main на момент релиза, и будет перезапускаться при любых новых merge’ах в qa. Более того, статус будет отображаться в pull request, и мы сможем использовать дополнительные возможности вроде обязательных проверок статуса в GitHub, чтобы дополнительно убедиться, что мы сливаем только успешные и протестированные изменения.
  • On-merge job на нашем окружении qa. Он будет запускаться каждый раз, когда кто-то делает merge. Этот вариант можно выбрать, если вы не хотите ждать завершения CI-пайплайна, когда открываете релиз. Однако он не покажет статус в release PR, и мы не сможем блокировать merge релиза на основании статуса запуска. При таком подходе владелец релиза всё равно должен следить за merge’ами и статусом последнего запуска перед merge.

Иерархическое продвижение приносит изменения, которые ещё не готовы для продакшена, из-за чего релизы стопорятся. Как этим управлять?

Процесс выбора конкретных коммитов, которые нужно перенести в другую ветку, называется cherry-picking.

Cherry Picking diagramCherry Picking diagram

Может возникнуть соблазн перейти на менее стандартную стратегию ветвления, чтобы этого избежать — наша коллега Grace Goheen написала об этом свои мысли и привела примеры — стоит прочитать!

dbt не выполняет операции cherry-picking, и это нужно делать через командную строку или интерфейс Git-платформы, если там есть такая опция. Мы согласны с Grace — cherry-picking требует очень хорошего понимания Git-операций и состояния веток; а если делать его неаккуратно, он может породить массу других проблем, которые сложно разрулить. Мы обычно видим, что описанные нами CI-процессы вместо этого сдвигают то, что считается «первым» одобрением PR: PR можно одобрить не только по коду и синтаксису коллегой, но и по выходным данным, выбирая из объектов, собранных в CI-схеме. Это убирает много проблем, связанных с кодом, который невозможно слить в продакшен.

Также мы используем другие возможности, которые помогают в сложные моменты:

  • Флаг команды --exclude помогает исключать сборку моделей в джобе
  • Конфигурация enabled помогает не выполнять модели ни в одном джобе как более долгосрочное решение
  • Использование contracts и versions помогает смягчать «ломающие» изменения кода между командами в dbt Mesh
  • Unit tests и data tests, вместе с практиками про минимальные требования к каждой модели, помогают нам постоянно проверять ожидания (см. пакет dbt_meta_testing)
  • Использование пакета dbt audit helper или включение advanced CI в наших continuous integration jobs помогает понять, какое влияние наши изменения оказывают на исходный набор данных

Если вы видите, что вам регулярно нужно делать cherry-pick, оценка ваших процессов ревью и quality assurance — и того, где именно они происходят в пайплайне — может сильно помочь понять, как этого избежать.

Что если плохое изменение всё же дошло до продакшена?

Процесс исправления main напрямую называется hotfix. Это нужно делать локально через Git или через интерфейс Git-платформы, потому что IDE dbt опирается на ветку, которую вы задаёте как базовую для разработчиков (в нашем случае — qa).

Паттерн для hotfix’ов в иерархическом продвижении выглядит так:

Hotfix diagramHotfix diagram

Обычно это делается так:

  1. Создайте ветку от main, затем внесите изменение и протестируйте исправление.
  2. Откройте PR в main, добейтесь одобрения, затем слейте. Исправление теперь в продакшене.
  3. Переключитесь на qa и выполните git pull, чтобы убедиться, что она обновлена и соответствует remote.
  4. Слейте main в qa: git merge main.
  5. Выполните git push, чтобы отправить изменения обратно в remote.
  6. На этом этапе в нашем примере разработчикам в IDE dbt Cloud будет показано, что в их базовой ветке есть изменения, и они смогут сделать ”Pull from remote”. Однако, если вы используете больше одной промежуточной ветки, вам нужно будет продолжать разрешать ветки иерархически, пока вы не обновите ветку, от которой базируются разработчики.

Что если мы хотим использовать больше одной промежуточной ветки в нашей стратегии?

По нашему опыту, более одной промежуточной ветки нужно редко. Чем больше шагов между вами и main, тем больше препятствий нужно преодолевать, чтобы вернуться к ней. Если команда не подготовлена, это создаёт большой оверхед для development operations. Поэтому мы не рекомендуем добавлять ветки без необходимости. Команды, у которых успешно получается работать с большим числом «стволов» (trunks), обычно имеют достаточно людей, которые могут выделить время на управление и сопровождение этих процессов.

A git strategy with more branchesA git strategy with more branches

Такая структура чаще всего нужна, когда есть требования использовать разные версии данных (например, «очищенные» данные) разным командам, но при этом работать с одними и теми же изменениями кода. Эта структура позволяет каждой команде иметь выделенное окружение для деплоев. Пример:

  1. Разработчики работают на мок-данных в своих feature-ветках и сливаются в qa для end-to-end и over-time тестирования всех слитых изменений на мок-данных перед релизом в preproduction.
  2. После того как qa слита в preproduction, используемые исходные данные переключаются на «очищенные» продакшен-данные, и другие роли могут начать смотреть и проверять, как эти данные работают, прежде чем они попадут в продакшен.
  3. После того как preproduction слита в main, используемые исходные данные переключаются на продакшен-наборы данных.

Чтобы показать сравнение, тот же кейс можно покрыть более простой стратегией ветвления — с использованием Git-тегов и переменных окружения dbt для переключения исходных данных:

  • Indirect Promotion:

    Tagging in Indirect PromotionTagging in Indirect Promotion
  • Direct Promotion:

    Tagging in Direct PromotionTagging in Direct Promotion

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

  • Можем ли мы точно описать use case каждой ветки?
  • Кто отвечает за контроль над любыми новыми ветками?
  • Кто ключевые участники процесса продвижения между ветками и за что они отвечают?
  • Для каких основных веток нам нужны dbt Cloud deployment jobs?
  • На каких стадиях PR нам нужны continuous integration jobs?
  • Какие правила для основных веток или PR-шаблоны нам нужно добавить?

Ответив на эти вопросы, вы сможете следовать тем же рекомендациям, что и в наших примерах, для настройки дополнительных веток.

Только для direct promotion

Нам нужно промежуточное окружение, но мы не хотим менять стратегию ветвления! Можно ли как-то отразить то, что в разработке?

Git releases/tags — это механизм, который помогает помечать конкретный commit SHA. Deployment-окружения в dbt Cloud могут использовать их так же, как и custom branch. Команды используют это либо чтобы «прибить» окружения к коду на конкретный момент времени, либо как вариант отката (roll-back), если понадобится.

Мы можем использовать метод «пиннинга», чтобы создать промежуточное окружение. Пример:

  • Мы создаём release-тег v2 в нашем репозитории.
  • В настройке custom branch для Production-окружения указываем ветку v2. Джобы Production теперь будут выкачивать код на v2.
  • Мы настраиваем окружение под названием “QA”, указав в custom branch значение main. Для database и schema мы указываем базу qa и схему analytics. Джобы, созданные с этим окружением, будут выкачивать код из main и собирать его в qa.analytics.
Tagging in Direct Promotion to create a middle environmentTagging in Direct Promotion to create a middle environment

Как перейти со стратегии direct promotion на стратегию indirect promotion?

Вот дополнительные шаги настройки в двух словах (используем имя qa для нашего промежуточного окружения) — за деталями обязательно прочитайте раздел про indirect promotion:

  • Git-платформа
    • Создайте новую ветку qa, производную от main
    • Защитите qa правилами защиты веток (branch protection)
  • dbt Cloud
    • Development: переключите окружение на опцию custom branch и укажите qa. Теперь разработчики будут базироваться на коде из qa.
    • Continous Integration: если у вас уже есть джоб для этого, убедитесь, что custom branch изменён на qa. Это изменит триггер CI job: он будет запускаться на pull request’ы в qa.

На этом этапе ваши разработчики будут следовать процессу indirect promotion, а вы сможете продолжать настраивать остальное в фоне. Вам всё ещё может понадобиться настроить базу данных, права на базу, окружения, deployment jobs и т. д. Вот короткий чеклист, который поможет! Для гораздо большего количества деталей вернитесь к нашему разделу про indirect promotion:

  • Решите, хотите ли вы разворачивать QA-код. Многие разворачивают, чтобы использовать deferral и Advanced CI. Если да:**

    • Создайте базу данных, где будут собираться объекты
    • Настройте service account для QA и выдайте ему все нужные права на создание и изменение содержимого этой базы. Также у него должен быть доступ только на чтение (select-only) к raw-данным.
    • Настройте окружение QA в dbt Cloud, обязательно подключив его к нужным database и schema, куда вы хотите собирать деплои.
    • Настройте deployment jobs, используя QA-окружение.
    • Если вы хотите использовать deferral или advanced-фичи в CI, сначала убедитесь, что у вас есть успешный запуск в QA, а затем укажите deferral setting в CI job на QA-окружение.
  • Решите, нужен ли вам CI на release pull request’ах (из qa в main). Если да:

    • Настройте окружение под названием “Release CI”
    • Настройте continuous integration job с использованием окружения “Release CI”
    • Если вы хотите использовать deferral или advanced CI, делайте defer на ваше production-окружение.

Comments

Loading