# Рекомендации для участников проектов dbt

Будь то `dbt-labs/dbt`, адаптеры, пакеты или сам этот сайт документации, участие в разработке кода с открытым исходным кодом или доступным для просмотра исходным кодом, на котором строится экосистема dbt, — отличный способ поделиться знаниями, вырасти как разработчик и внести свой вклад в сообщество. Цель этой страницы — помочь вам понять, чего ожидать при участии в проектах экосистемы dbt.

Вы видели в других проектах что-то, что вам понравилось, и считаете, что мы могли бы перенять этот опыт? [Создайте обсуждение на форуме сообщества dbt](https://discourse.getdbt.com) или начните разговор в [Slack сообщества dbt](https://www.getdbt.com/community/join-the-community) (например, в каналах `#community-strategy`, `#dbt-development`, `#package-ecosystem`, `#adapter-ecosystem`). Мы всегда рады вашим отзывам и предложениям!

## Принципы

### dbt — командный вид спорта

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

Есть и вполне практическая причина: разработка «в публичном поле» ставит коллективные знания и опыт выше опыта любого отдельного человека. У нас нет практики работы с каждой базой данных, каждой операционной системой, каждой средой безопасности и т. д. Мы полагаемся на сообщество пользователей, которое помогает оттачивать функциональность продукта и документацию для самого широкого спектра контекстов, в которых он используется. Благодаря этому dbt становится результатом работы тысяч людей, а не нескольких десятков.

### Мы серьезно относимся к нашей роли хранителей стандарта

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

Мы также считаем, что dbt как фреймворк должен быть достаточно расширяемым, чтобы [«делать простые вещи простыми, а сложные — возможными»](https://en.wikipedia.org/wiki/Perl#Philosophy). Исходя из этого, мы *не* считаем уместным, чтобы в dbt «из коробки» существовало решение для каждой нишевой задачи. Пользователи обладают гибкостью для реализации множества нестандартных сценариев, определяя собственные макросы, материализации, хуки и многое другое. Мы рассматриваем своей ответственностью как мейнтейнеров решение о том, когда что‑то должно быть просто «возможным» — через макросы, пакеты и т. д., — а когда что‑то должно быть «простым» — то есть встроенным в стандарт dbt.

Так когда же мы говорим «да» новым возможностям в dbt? Среди сигналов, на которые мы обращаем внимание:

* Голоса (upvotes) за issues в наших GitHub‑репозиториях
* Пакеты dbt с открытым исходным кодом, пытающиеся закрыть существующий пробел
* Технические достижения в экосистеме

А пока — мы будем стараться отвечать на новые issues следующим образом:

* Чётко объяснять, попадает ли предложенная функциональность в предполагаемые границы source‑available компонентов dbt
* Давать контекст (включая ссылки на связанные issues)
* Предлагать альтернативы и обходные пути
* По возможности указывать на код, который может помочь контрибьюторам из сообщества

### Инициатива — это все

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

* Если вы открываете отчет об ошибке, она с большей вероятностью будет идентифицирована.
* Если вы открываете запрос на функцию, он с большей вероятностью будет обсужден.
* Если вы комментируете проблему, взаимодействуя с идеями и связывая ее с вашим собственным опытом, она с большей вероятностью будет приоритетной.
* Если вы открываете PR для исправления выявленной ошибки, она с большей вероятностью будет исправлена.
* Если вы комментируете существующий PR, чтобы подтвердить, что он решает конкретную проблему для вашей команды на практике, он с большей вероятностью будет объединен.

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

## Практические аспекты

### Обсуждения

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

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

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

### Проблемы

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

#### Лучшие практики для проблем

* Проблемы **не** предназначены для поддержки / устранения неполадок / помощи в отладке. Пожалуйста, ознакомьтесь с [поддержкой dbt](https://docs.getdbt.tech/docs/dbt-support.md) для получения более подробной информации и предложений о том, как получить помощь.
* Всегда сначала ищите существующие проблемы, чтобы увидеть, не возникла ли у кого-то еще такая же идея / не нашел ли кто-то ту же ошибку, что и вы.
* Многие репозитории dbt предлагают шаблоны для создания проблем, такие как отчет об ошибке или запрос новой функции. Если доступно, пожалуйста, выберите соответствующий шаблон и заполните его по мере возможности. Эта информация помогает нам (и другим) понять вашу проблему.

##### Вы нашли существующую проблему, которая вас интересует. Что вам следует сделать?

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

##### Вы открыли новую проблему. Чего вы можете ожидать?

В наших наиболее важных репозиториях (таких как `dbt-labs/dbt`) мы стремимся как можно быстрее отвечать на новые issues. Первым ответом часто бывает краткое подтверждение того, что сопровождающие проекта знают о проблеме, с обозначением того, насколько срочной мы её считаем. В зависимости от характера вашей проблемы её решение может хорошо подойти для вклада со стороны — от вас или другого участника сообщества.

**Что делать, если вы создаёте issue в другом репозитории?** У нас есть инженерные команды, которые активно поддерживают [`dbt-labs/dbt`](https://github.com/dbt-labs/dbt), где размещены как v1, так и v2. Если вы вносите вклад в репозиторий `dbt-labs/dbt`, учитывайте следующее:

* v2 находится в ветке `main`
* v1 находится в ветке `latest.1`, а также в библиотеках компонентов v1 ([`dbt-common`](https://github.com/dbt-labs/dbt-common) + [`dbt-adapters`](https://github.com/dbt-labs/dbt-adapters) (который также включает адаптеры, поддерживаемые dbt Labs). `dbt-adapters` относится только к v1.

За прошедшие годы мы открыли исходный код ряда других программных проектов, и для большинства из них мы не гарантируем такой же уровень активности и поддержки. Проверьте, есть ли ответы на другие недавние issues и когда был добавлен последний коммит в ветку `main`.

**Вы не уверены в статусе своего issue.** Если ваш issue находится в активно поддерживаемом репозитории и имеет метку `status:triage`, мы знаем, что на него нужно ответить. Если issue уже прошёл первичный разбор, но ещё не получил приоритет, это может означать следующее:

* предполагаемый scope или пользовательский опыт предлагаемой фичи требуют дальнейшей проработки со стороны мейнтейнера;
* мы считаем, что необходимое изменение кода слишком сложное для внешнего контрибьютора.

Мы постараемся объяснить открытые вопросы или сложность, и когда / почему мы могли бы предвидеть ее приоритизацию.

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

#### Метки проблем

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

В некоторых случаях правильное решение открытой проблемы может быть косвенно связано с кодовой базой. Правильный путь вперед может быть в другой кодовой базе (мы перенесем ее), обновлении документации или изменении, которое вы можете сделать сами в пользовательском коде. В других случаях проблема может описывать функциональность, которую хранители не хотят или не могут включить в основную кодовую базу. В этих случаях хранитель закроет проблему (возможно, используя метку `wontfix`) и объяснит, почему.

Многие метки следуют модели `facet:value` с пространством имён, где каждый фасет отвечает на один вопрос о задаче — к какому виду работ она относится, какую подсистему затрагивает, на какой движок dbt нацелена и так далее. Некоторые фасеты принимают ровно одно значение, другие — несколько. Вам не нужно назначать эти метки самостоятельно, но понимание их значений поможет отслеживать состояние задачи.

| Фасет         | Примеры значений                                                                                                                  | Значение                                                                                                                      |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `type:`       | `type:bug`, `type:feature`, `type:docs`, `type:tech-debt`, `type:epic`, `type:good-first-issue`                                   | Вид работ. Ровно одно значение на задачу.                                                                                     |
| `area:`       | `area:static-analysis`, `area:engine`, `area:compute`, `area:adapters`, `area:vscode`, `area:wizard`, `area:autofix`, `area:cicd` | Подсистема, которую затрагивает задача.                                                                                       |
| `adapter:`    | `adapter:bigquery`, `adapter:snowflake`, `adapter:databricks`, `adapter:postgres`, …                                              | Адаптер или диалект SQL, к которому относится задача.                                                                         |
| `engine:`     | `engine:v1`, `engine:v2`                                                                                                          | Движок dbt, которого касается задача: `engine:v1` — движок на Python (dbt v1); `engine:v2` — версия v2, переписанная на Rust. |
| `priority:`   | `priority:p0`, `priority:p1`, `priority:p2`                                                                                       | Срочность, определённая сопровождающими при первичном разборе задачи.                                                         |
| `status:`     | `status:triage`, `status:needs-repro`, `status:has-repro`, `status:ready-for-review`                                              | Текущий этап обработки задачи.                                                                                                |
| `resolution:` | `resolution:wontfix`                                                                                                              | Причина закрытия задачи без изменений в коде.                                                                                 |

Автоматизация назначает новым задачам метку `status:triage`, обозначающую, что они ожидают первого ответа сопровождающего. У старых задач также могут сохраняться прежние метки без пространства имён, такие как `bug`, `enhancement`, `good_first_issue`, `help_wanted`, `duplicate`, `stale` и `wontfix`. Они соответствуют приведённым выше фасетным меткам (`bug` → `type:bug`, `enhancement` → `type:feature`, `good_first_issue` → `type:good-first-issue`, `wontfix` → `resolution:wontfix` и так далее) и сохраняются для преемственности. Пока переход не завершён, вы можете встретить любой из этих наборов меток.

### Pull-запросы

**Каждый PR должен быть связан с проблемой.** Почему? Прежде чем вы потратите много времени на работу над вкладом, мы хотим убедиться, что ваше предложение будет принято. Вы должны сначала открыть проблему, описав желаемый результат и наметив планируемое изменение. Если вы нашли старую проблему, которая уже открыта, прокомментируйте ее с планом вашей реализации *до* того, как начнете работу над открытием pull-запроса.

**PR должны включать надежное тестирование.** Комплексное тестирование в рамках pull-запросов имеет решающее значение для стабильности dbt. Приоритетное внимание к надежному тестированию обеспечивает надежность нашей кодовой базы, минимизирует непредвиденные проблемы и защищает от потенциальных регрессий. **Мы не можем объединять изменения, которые могут привести к несовместимости с задокументированными поведениями.** Мы понимаем, что создание тщательных тестов часто требует значительных усилий, и ваша приверженность этому процессу значительно способствует общей надежности проекта. Спасибо за вашу приверженность поддержанию целостности нашей кодовой базы и опыта всех, кто использует dbt!

**PR проходят два этапа ревью.** Сначала мы стараемся дать обратную связь о том, насколько предложенная реализация уместна с точки зрения продукта и удобства использования. На этом этапе мы закрываем PR, которые, по нашему мнению, выходят за рамки dbt или могут привести к непоследовательному пользовательскому опыту. Многие из них содержат отличные идеи для дополнительной функциональности, которую лучше реализовать в виде пакета или плагина. Это важная часть нашей роли как сопровождающих проекта; мы всегда открыты к обсуждению разногласий. Если PR проходит этот первый этап, мы ставим его в очередь на ревью кода, в ходе которого стараемся самостоятельно протестировать изменения и предоставить подробную обратную связь.

**Мы получаем больше PR, чем можем тщательно отревьюить, протестировать и смержить.** У наших команд ограниченные ресурсы, и наш главный приоритет — поддержание хорошо очерченного и качественного фреймворка для десятков тысяч людей, которые используют его каждую неделю. Поэтому нам приходится отдавать приоритет общей стабильности и запланированным улучшениям, а не длинному хвосту нишевых потенциальных функций. Чтобы повысить шансы на успех, сразу указывайте, по каким именно аспектам вам особенно важна обратная связь, и объясняйте, что будет значить принятие предложенного изменения для вас, вашей команды и других участников сообщества. Небольшие PR, решающие чётко ограниченные задачи, как правило, рассматриваются проще и быстрее. Два примера PR, внесённых участниками сообщества:

* [(dbt-core#9347) Исправление конфигурации преобразования предупреждений тестов в ошибки](https://github.com/dbt-labs/dbt-core/pull/9347)

* [(dbt-core#9863) Более информативное сообщение об ошибке при попытке выбрать отключённую модель](https://github.com/dbt-labs/dbt-core/pull/9863)

* [(dbt-labs/dbt#9347) Исправлена настройка преобразования предупреждений тестов в ошибки](https://github.com/dbt-labs/dbt/pull/9347)

* [(dbt-labs/dbt#9863) Улучшено сообщение об ошибке при попытке выбрать отключённую модель](https://github.com/dbt-labs/dbt/pull/9863)

* **Тесты, тесты, тесты.** Когда вы открываете PR, будут запущены тесты и проверки кода. (По соображениям безопасности некоторые из них могут потребовать одобрения мейнтейнера.) Мы не будем мержить PR с падающими тестами. Если вы не уверены, почему тест не проходит, пожалуйста, сообщите об этом — мы постараемся вместе разобраться в причинах.

* **Contributor License Agreement** (CLA): Это соглашение гарантирует, что мы можем принять ваш код, не беспокоясь о неожиданных последствиях для авторских прав или лицензирования open source или source-available ПО dbt. Подробнее см.: ["Contributor License Agreements"](https://docs.getdbt.tech/community/resources/contributor-license-agreements.md)

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

* **Тесты, тесты, тесты.** Когда вы открываете PR, запускаются тесты и проверки кода. (Из соображений безопасности для запуска некоторых из них может потребоваться одобрение сопровождающего проекта.) Мы не принимаем PR с непрошедшими тестами. Если вы не уверены, почему тест завершается с ошибкой, сообщите нам, и мы постараемся разобраться вместе.

* **Лицензионное соглашение с участником** (CLA): Оно позволяет нам принимать ваш код, не опасаясь непредвиденных последствий для авторских прав или лицензий на программное обеспечение dbt с открытым или доступным для просмотра исходным кодом. Подробнее читайте в разделе: [«Лицензионные соглашения с участниками»](https://docs.getdbt.tech/community/resources/contributor-license-agreements.md)

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

* **Метка Semver:** В некоторых репозиториях каждый пул-реквест должен иметь ровно одну метку: `semver:patch` (исправления ошибок и другие безопасные изменения) или `semver:minor` (новые возможности, не нарушающие обратную совместимость); метка `semver:major` не допускается. В таких репозиториях CI проверяет соблюдение этого требования.

### Включение изменений в релизы

#### dbt v1

Как исправления ошибок, так и новые возможности с обратной совместимостью будут включены в [следующий минорный выпуск dbt v1](https://docs.getdbt.tech/docs/dbt-versions.md#how-dbt-v1-uses-semantic-versioning). Исправления регрессий и новых ошибок, присутствовавших в первоначальном выпуске минорной версии, будут перенесены в версии с [активной поддержкой](https://docs.getdbt.tech/docs/dbt-versions.md). Другие исправления ошибок могут быть перенесены в предыдущие версии, если мы с высокой уверенностью считаем, что они затрагивают лишь ограниченную область и не вызовут непредвиденных побочных эффектов.

#### dbt v2

dbt v2 выпускается непрерывно и включает весь код и все функциональные возможности, доступные в слое с открытым исходным кодом, а также дополнительные возможности. Номера версий dbt OSS и dbt v2 сходятся на v2.0.0.

Мажорная версия нашего [продукта с открытым исходным кодом](https://docs.getdbt.tech/docs/dbt-versions/dbt-upgrade/upgrading-to-v2.md) построена на среде выполнения v2. Изменения в `dbt-core`, предназначенные для серии v2.x, подчиняются тем же принципам, что и для v1.x: исправления ошибок и возможности с обратной совместимостью включаются в ближайший выпуск.
