Функция CODEOWNERS позволяет определить ответственных за отдельные части репозитория. Ответственными могут быть пользователи и группы. Изменения, затрагивающие файлы, указанные в CODEOWNERS, должны получить апрув от владельцев кода.
Использование CODEOWNERS помогает:
- требовать апрувы от доменных экспертов для важных директорий;
- упростить процесс поиска «ответственных» за конкретный участок кода.
CODEOWNERS дополняет механизм правил апрува, но не заменяет их. В отличие от правил апрува, которые задаются вручную в UI, CODEOWNERS работает через файл CODEOWNERS в репозитории.
Как работает CODEOWNERS
CODEOWNERS — текстовый файл в репозитории.
Deckhouse Code использует его для определения владельцев файлов, участвующих в запросе на слияние.
Ищется в трёх местах (по приоритету):
./CODEOWNERS../docs/CODEOWNERS../.gitlab/CODEOWNERS.
Используется только первый найденный файл.
Если в проекте существует несколько файлов и вы сейчас просматриваете неприоритетный, то увидите соответствующее сообщение.

Валидация файла CODEOWNERS
Валидация помогает увидеть ошибки в файле на этапе редактирования.
Если файл валиден, отображается соответствующее сообщение:

Если файл невалиден, будут отображены проблемные строки и тип ошибки:

Существует 4 вида ошибок валидации:
- У владельцев нет доступа в этот проект или их уровень доступа недостаточен — как минимум один из владельцев не имеет достаточных прав в проекте.
- Пробелы в пути — если путь содержит пробелы, нужно их экранировать символом
\. - Нет владельцев — не указано ни одного владельца.
- Незакрытый раздел — не хватает символа закрытия раздела
].
Где применяется CODEOWNERS
Если MR, изменяющий файл, попадает под правила CODEOWNERS, то необходимо получить апрувы от владельцев.
Формат CODEOWNERS
Строка правила:
<путь или паттерн> <список владельцев>
Владельцы:
@user;@group;@group/subgroup;- роли:
@@developer,@@maintainer,@@owner.
Примеры
# Владелец всех файлов
* @default-team
# README.md только в корне
/README.md @docs-team
# Все Ruby-файлы
*.rb @backend-team
# Вся директория config
/config/ @devops
# README.md в любом месте
README.md @docs
Паттерны путей
Deckhouse Code использует подстановочные символы:
*— любые символы кроме/.**— матч нескольких уровней директорий./dir/— только указанная директория.*.md— все Markdown-файлы./config/**/*.rb— все Ruby-файлы внутриconfig/*на всех уровнях.
Примеры паттернов
/docs/* @docs-one # один уровень
/docs/** @docs-two # рекурсивно
/app/**/*.rb @ruby-team
Секции CODEOWNERS
В файле CODEOWNERS секции — это именованные области, которые анализируются отдельно и всегда применяются. Пока вы не определите ни одной секции, Deckhouse Code рассматривает весь файл CODEOWNERS как одну единственную секцию.
Особенности использования CODEOWNERS:
- Deckhouse Code рассматривает записи без секций, включая правила, определённые до первой секции, как отдельную, безымянную секцию.
- Каждая секция обрабатывает свои правила отдельно.
- Если путь к файлу соответствует нескольким записям внутри одной секции, используется только последняя подходящая запись в этой секции.
- Если путь к файлу соответствует записям в нескольких секциях, используется последняя подходящая запись в каждой секции.
Например, в файле CODEOWNERS со следующими секциями, определяющими владельцев для README:
* @root
[README Owners]
README.md @user1 @user2
internal/README.md @user4
[README other owners]
README.md @user3
Владельцы для README.md в корневой директории:
@root— из безымянной секции.@user1и@user2— из секции[README Owners].@user3— из секции[README other owners].
Владельцы для internal/README.md:
@root— из безымянной секции.@user4— из секции[README Owners]. (ИREADME.md, иinternal/README.mdподходят под правила секции, но используется только последняя подходящая запись в этой секции).@user3— из секции[README other owners].
В виджете запроса на слияние каждый владелец кода отображается под своим ярлыком.

Детальный пример: сложная комбинация секций
Ниже — пример реального промышленного файла, показывающий:
- секции с разным количеством апрувов;
- переопределение владельцев;
- опциональные секции;
- исключения;
- наследование секций с одинаковыми именами.
# Глобальные настройки
* @fallback-team
!*.lock # lock-файлы не требуют апрувов
!**/generated/** # автоматическая генерация
[Backend][2] @backend-core
# Требуются 2 апрува от backend-core для любого Ruby-кода
app/**/*.rb
# Но для критических моделей определяем другой порядок
app/models/**/*.rb @backend-core @security-team
# А вот эта модель — исключение, владелец другой
app/models/legacy/**/*.rb @migration-team
[Backend]
# Дополнение секции: теперь Backend включает также SQL
db/**/*.sql @db-team
[Ruby Optional]
# Дополнительная подсветка владельцев, апрувы НЕ обязательны
^[Ruby Optional]
*.rb @ruby-advisors
[Frontend][3]
# Для UI требуется 3 апрува
*.vue @frontend-team
*.js @frontend-team
# переопределение: конкретный файл → конкретный человек
frontend/critical_entry.vue @frontend-lead
[Docs]
*.md @technical-writers
[Docs]
# переопределение: README всегда принадлежит docs-lead
README.md @docs-lead
Особенности примера:
- секция
[Backend]объявлена дважды → Deckhouse Code объединит её; [Backend][2] @backend-coreзадаёт обязательные 2 апрува;[Frontend][3]требует 3 апрува от фронтенда;[Ruby Optional]отмечена как опциональная — владельцы видны, но их апрув не обязателен;- исключения
!*.lockи!**/generated/**означают, что эти файлы вообще не требуют апрувов.
Исключения (!)
Используются для исключения файлов внутри секции:
* @default
!package-lock.json
!**/generated/**
После исключения файл не может быть снова включён в ту же секцию.
Порядок обработки правил
Правила обрабатываются в соответствии со следующим порядком:
- Deckhouse Code читает файл сверху вниз.
- В пределах одной секции правила с одинаковым путём переопределяют предыдущие.
- Если файл подходит под несколько секций — владельцы из всех этих секций добавляются.
- Секции не переопределяют друг друга — они независимы.
Кто может быть владельцем (eligible owners)
1. Пользователи (через @username)
Пользователь считается валидным владельцем, если:
- Имеет прямое членство в проекте (Developer, Maintainer или Owner).
- Имеет членство в группе проекта (включая наследуемое: группа проекта, родительские группы, предки родительских групп).
- Является прямым или унаследованным участником группы, которая напрямую приглашена в проект.
- Является прямым но не унаследованным участником группы которая приглашена в группу проекта.
- Является прямым но не унаследованным участником группы которая приглашена в предка группы проекта.
Если подытожить, то подходят все пользователи которые отображаются на странице участников проекта с ролью developer или выше.
Не считается владельцем, если:
- заблокирован,
- доступ отозван,
- роль ниже Developer.
2. Группы (через @group или @group/subgroup)
Группа может быть владельцем только если:
- Она напрямую приглашена в проект с ролью Developer+ (через “Пригласить группу”).
- Владельцами считаются только прямые участники этой группы.
Наследуемые участники родительских групп владельцами не считаются.
3. Роли (через @@role)
Формат:
@@developer
@@maintainer
@@owner
Особенности:
- учитываются только прямые участники проекта;
- члены групп в расчёт не входят;
- роли не наследуют друг друга (
@@developerНЕ включает maintainer’ов).
Можно указывать несколько ролей в одной строке:
file.md @@developer @@maintainer
Взаимодействие с правилами апрува
CODEOWNERS и правила апрувов работают независимо, но их требования суммируются.
Пример:
- правило
Securityтребует 1 апрув; - секция
[Backend][2]требует 2 апрува; - MR меняет backend-файл.
Итог: необходимо 3 апрува.
Отключение проверок CODEOWNERS
Проверки CODEOWNERS, которые включены в Deckhouse Code по умолчанию, можно отключить на уровне проекта. Это удобно, когда в проекте есть файл CODEOWNERS, но требовать апрувы от владельцев кода не нужно.
Чтобы отключить проверки, перейдите в раздел «Проект» → «Настройки» → «Запросы на слияние» → раздел дополнительных настроек правил апрува и выберите настройку «Отключить проверки одобрения Code Owners».

При отключении проверки CODEOWNERS пропускаются во всём проекте:
- запросы на слияние не блокируются из-за отсутствующих апрувов от владельцев кода;
- владельцы кода не определяются для изменённых файлов — список применимых записей пуст;
- изменение настройки сразу применяется к уже открытым запросам на слияние.
Проверка синтаксиса файла CODEOWNERS при этом продолжает работать. Файл можно валидировать даже при отключённых проверках.
Автоматическое назначение владельцев кода проверяющими
Владельцев кода, соответствующих изменённым файлам, можно автоматически назначать проверяющими запроса на слияние.
Для этого перейдите в раздел «Проект» → «Настройки» → «Запросы на слияние» → «Автоматическое назначение проверяющих» и выберите настройку «Автоматически назначать владельцев кода проверяющими».

По умолчанию настройка выключена. При её включении владельцы кода назначаются проверяющими:
- при создании запроса на слияние сразу в готовом статусе (не в статусе черновика);
- при снятии статуса черновика с запроса на слияние.
При автоматическом назначении действуют следующие ограничения:
- для черновиков назначение не выполняется;
- если у запроса на слияние уже есть проверяющие, автоматическое назначение не выполняется — назначенные вручную проверяющие сохраняются;
- автор запроса на слияние не может быть назначен проверяющим;
- назначаются только пользователи, у которых есть доступ на чтение запроса на слияние;
- если в проекте запрещено назначать нескольких проверяющих, назначается только первый владелец кода.
Рекомендации по оформлению
При оформлении файла CODEOWNERS следуйте рекомендациям:
- Сначала задавайте широкие правила (
* @team). Далее уточняющие (app/**/*.rb @backend-team). - Используйте секции для лучшей структуры и наглядности.
- Избегайте дубликатов — последнее правило в секции имеет приоритет.
- Опциональные секции полезны для подсветки экспертов без обязательных апрувов.
Пример финального файла
# Глобальные владельцы
* @default-team
# Исключения
!yarn.lock
!**/generated/**
[Backend][2]
app/**/*.rb @backend-core
[Frontend][3]
*.vue @frontend-team
*.js @frontend-team
^[Docs]
*.md @docs-team
[Critical Overrides]
/config/production.yml @ops-lead