Как начать работать со стратегиями ветвления в git и dbt
Привет! Мы — Кристин и Кэрол, Resident Architects в dbt Labs. Наша повседневная работа связана с тем, чтобы помогать командам достигать как технических, так и бизнес-ориентированных целей. Работая с самым разным кругом клиентов — от небольших стартапов до крупных корпораций — мы накопили ценный опыт в сопровождении команд при внедрении архитектуры, которая решает их ключевые болевые точки.
Информация, которой мы собираемся поделиться, основана не только на нашем опыте — мы регулярно сотрудничаем с другими экспертами, такими как Taylor Dunlap и Steve Dowling, которые внесли значительный вклад в формирование этих рекомендаций. Их работа заключается в том, чтобы быть критически важным мостом для команд между реализацией и бизнес-результатами, в конечном итоге помогая выработать целостное техническое видение через выявление проблем и решений.
Зачем мы здесь?
Мы помогаем командам с архитектурой dbt, которая включает в себя инструменты,
процессы и конфигурации, используемые для начала разработки и деплоя с dbt.
За кулисами происходит множество решений, направленных на стандартизацию этих
составляющих — и во многом они определяются тем, каким мы хотим видеть процесс
разработки. Стремление к идеальному workflow часто приводит к тому, что
команды застревают в бесконечном планировании и обсуждениях, что замедляет или даже
полностью останавливает разработку. Если вам это знакомо, мы надеемся, что наши
рекомендации помогут вам чувствовать себя увереннее и начать разблокировать
разработку — даже если пока не всё до конца продумано!
Есть три основных инструмента, которые играют ключевую роль в разработке с dbt:
- Репозиторий
Содержит код, который мы хотим изменить или задеплоить, а также инструменты для управления процессами изменений. - Платформа данных
Содержит данные для входных источников (загружаемые из других систем), а также базы данных и схемы для выходных данных, плюс управление правами доступа к объектам. - Проект dbt
Помогает управлять процессами разработки и деплоя нашего кода на платформу данных (и делает ещё много полезных вещей!)
Независимо от того, как именно вы определяете 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 для этой стратегии:
Как выглядит workflow разработки для команды?
Структура:
feature— индивидуальная ветка разработчика, где выполняются изменения по задачеmain— ветка с «production»-версией кода
Workflow:
- Development: я создаю ветку
featureотmain, чтобы вносить изменения, тестировать их и проводить первичную самопроверку - Quality Assurance: я открываю pull request, сравнивающий
featureсmain, который затем проходит ревью у коллег (обязательно), стейкхолдеров или предметных экспертов (SME). В этой стратегии мы настоятельно рекомендуем привлекать стейкхолдеров или SME к PR, потому что следующий шаг меняетmain. - Promotion: после всех необходимых одобрений и проверок я мержу изменения в
main - Deployment: после мержа и деплоя
mainдругие могут видеть и использовать мои изменения
Правила ветвления и вспомогательные механизмы репозитория
Как минимум мы рекомендуем настроить:
- Защиту ветки
main(например, такие настройки в GitHub), с требованиями:- все изменения через pull request (никаких прямых коммитов в
main) - pull request должен иметь как минимум одно одобрение ревьюера
- все изменения через pull request (никаких прямых коммитов в
- Шаблон PR (например, наш базовый шаблон PR) для
feature→main
Процессы и окружения dbt Cloud
Вот та же стратегия ветвления, но уже с процессами dbt Cloud, которые мы хотим использовать:
Чтобы создать jobs из диаграммы, нам нужны окружения dbt Cloud. Типовые конфигурации для этого сценария выглядят так:
| Loading table... |
Организация платформы данных
Теперь нужно определить, где именно мы будем создавать объекты на платформе данных. Для этого настраиваются параметры database и schema в окружениях. Вот та же диаграмма, но с отображением того, как объекты из веток попадают на платформу данных:
Дополним ранее созданную таблицу окружений dbt Cloud сопоставлением с платформой данных:
| Loading table... |
Здесь показаны конфигурации окружений, однако база данных по умолчанию задаётся на более высоком уровне — в connection (это обязательная настройка окружения). Deployment-окружения при необходимости могут переопределять database из connection.
Пример direct promotion
В этом примере Steve использует термин “QA” для обозначения окружения, которое собирает изменённый код из pull request’ов feature-веток. Это эквивалент нашего окружения “Continuous Integration” — отличный пример того, как можно выбирать названия, наиболее понятные вашей команде!
Косвенное продвижение (Indirect Promotion)
Косвенное продвижение добавляет больше шагов ответственности, поэтому эта стратегия ветвления лучше всего работает, когда вы можете определить людей, которые отлично понимают Git, чтобы вести управление ветками. Кроме того, время от разработки до продакшена становится дольше из‑за нагрузки от этих новых шагов, поэтому требуется хорошее управление проектом. Мы подробнее разберём это позже, но важно отметить, что именно здесь неподготовленные команды чаще всего испытывают трудности.
Косвенное продвижение добавляет другие долгоживущие ветки, которые производятся от main.
Самая простая версия косвенного продвижения — иерархическая структура с двумя «стволами»
— именно её мы чаще всего видим реализованной в косвенных рабочих процессах.
Иерархическое продвижение — это продвижение изменений обратно тем же путём, которым мы выводили ветки. Пример:
- промежуточная ветка создаётся от
main - feature-ветки создаются от промежуточной ветки
- feature-ветки сливаются обратно в промежуточную ветку
- промежуточная ветка сливается обратно в
main
Некоторые распространённые названия для промежуточной ветки, которые встречаются на практике:
qa: Quality Assuranceuat: User Acceptance Testingstagingилиpreprod: распространённая терминология в разработке ПО
В оставшейся части статьи мы будем называть нашу промежуточную ветку qa.
Вот рабочий процесс для этой стратегии:
Как выглядит рабочий процесс разработки глазами разработчика?
Изменения относительно нашего процесса 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будет развёрнута
Правила ветвления в репозитории и вспомогательные настройки
Как минимум, нам нравится настраивать:
- Защиту веток для
mainиqa(например, такие настройки для GitHub), требуя:- pull request (никаких прямых коммитов в
mainилиqa) - pull request должен иметь как минимум 1 одобрение от ревьюера
- pull request (никаких прямых коммитов в
- Шаблон PR (например, наш шаблон PR «из коробки») для PR из
featureвqa - Шаблон PR (например, наш шаблон PR «из коробки» для релизов) для PR из
qaвmain
Процессы и окружения dbt Cloud
Вот наша стратегия ветвления ещё раз, но теперь с процессами dbt Cloud, которые мы хотим включить:
Чтобы создать джобы на нашей схеме, нам нужны окружения dbt Cloud. Вот типичные конфигурации для такого сетапа:
| Loading table... |
Организация платформы данных
Теперь нужно сфокусироваться на том, где мы хотим собирать объекты в нашей платформе данных. Для этого нам нужно задать настройки database и schema в окружениях. Есть два распространённых варианта сопоставления кода, но прежде чем перейти к ним, вспомним это примечание из direct promotion:
Здесь мы показываем конфигурации окружений, но база данных по умолчанию задаётся на более высоком уровне — в подключении (а подключение — обязательная настройка окружения). Deployment-окружения при необходимости могут переопределять настройку базы данных из подключения.
-
Конфигурация 1: соответствие 1:1 для ресурсов
qaиmainВ этом паттерне CI-схемы создаются в базе данных вне Production и QA. Обычно так делают, чтобы базы данных соответствовали тому, что слито в их ветки. Вот наша схема, но теперь с сопоставлением на платформу данных для этого паттерна:Вот конфигурации для этого паттерна:
Loading table... -
Конфигурация 2: отражение инициативы рабочего процесса
В этом паттерне CI-схемы создаются в базе
qa, потому что это часть шага quality assurance. Вот наша схема, но теперь с сопоставлением на платформу данных для этого паттерна:
Indirect Promotion branches and how they relate to workflow initiative organization in the data platformВот конфигурации для этого паттерна:
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вmainrelease manager’ом и экспертами по предметной области или стейкхолдерами
Кроме того, одобренные изменения из feature-веток продвигаются вместе из
qa. - Из
-
Развертывание
Теперь есть две основные ветки, из которых можно разворачивать код:
qa: «рабочая» версия с изменениями; сюда сливаютсяfeaturemain: «продакшен» версия
Поскольку наши изменения накапливаются в ветке
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для тестирования релизов до их слияния.
Дальнейшие улучшения
Когда базовые конфигурации готовы, вы можете дополнительно настроить проект, подумав, какие ещё функции будут полезны под ваши нужды:
- Continuous Integration:
- Запуск и тестирование только изменённых моделей и их зависимостей
- Использование dbt clone для получения копии больших инкрементальных моделей в CI
- Development and Deployment:
- Использование настроек схем (schema configurations) в проекте, чтобы сильнее разделять данные в базе
- Использование настроек баз данных (database configurations) в проекте, чтобы переключать базы данных для сборки моделей
Часто задаваемые вопросы про 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.
Может возникнуть соблазн перейти на менее стандартную стратегию ветвления, чтобы этого избежать — наша коллега 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’ов в иерархическом продвижении выглядит так:
Обычно это делается так:
- Создайте ветку от
main, затем внесите изменение и протестируйте исправление. - Откройте PR в
main, добейтесь одобрения, затем слейте. Исправление теперь в продакшене. - Переключитесь на
qaи выполнитеgit pull, чтобы убедиться, что она обновлена и соответствует remote. - Слейте
mainвqa:git merge main. - Выполните
git push, чтобы отправить изменения обратно в remote. - На этом этапе в нашем примере разработчикам в IDE dbt Cloud будет показано, что в их базовой ветке есть изменения, и они смогут сделать ”Pull from remote”. Однако, если вы используете больше одной промежуточной ветки, вам нужно будет продолжать разрешать ветки иерархически, пока вы не обновите ветку, от которой базируются разработчики.
Что если мы хотим использовать больше одной промежуточной ветки в нашей стратегии?
По нашему опыту, более одной промежуточной ветки нужно редко. Чем больше шагов между вами и main, тем больше препятствий нужно преодолевать, чтобы вернуться к ней. Если команда не подготовлена, это создаёт большой оверхед для development operations. Поэтому мы не рекомендуем добавлять ветки без необходимости. Команды, у которых успешно получается работать с большим числом «стволов» (trunks), обычно имеют достаточно людей, которые могут выделить время на управление и сопровождение этих процессов.
Такая структура чаще всего нужна, когда есть требования использовать разные версии данных (например, «очищенные» данные) разным командам, но при этом работать с одними и теми же изменениями кода. Эта структура позволяет каждой команде иметь выделенное окружение для деплоев. Пример:
- Разработчики работают на мок-данных в своих
feature-ветках и сливаются вqaдля end-to-end и over-time тестирования всех слитых изменений на мок-данных перед релизом вpreproduction. - После того как
qaслита вpreproduction, используемые исходные данные переключаются на «очищенные» продакшен-данные, и другие роли могут начать смотреть и проверять, как эти данные работают, прежде чем они попадут в продакшен. - После того как
preproductionслита вmain, используемые исходные данные переключаются на продакшен-наборы данных.
Чтобы показать сравнение, тот же кейс можно покрыть более простой стратегией ветвления — с использованием Git-тегов и переменных окружения dbt для переключения исходных данных:
-
Indirect Promotion:
-
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.
Как перейти со стратегии 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.
- Development: переключите окружение на опцию custom branch и укажите
На этом этапе ваши разработчики будут следовать процессу 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