Введение
CI/CD строится на основе системы контроля версий — в статье разберём практики работы с Git, поддерживающие эффективный CI/CD процесс: модели ветвления, code review через pull/merge requests, и защищённые ветки, предотвращающие случайное попадание непроверенного кода в основную, «боевую» ветку.
Концепция
Модель ветвления определяет, как организуется параллельная разработка нескольких функций одновременно — от относительно простого Git Flow (отдельные ветки для функций, релизов, исправлений) до более лёгкого GitHub Flow (одна основная ветка плюс короткоживущие ветки функций, слитые через pull request после code review). Code review — обязательная проверка изменений другим участником команды перед слиянием в основную ветку, выявляющая проблемы (логические ошибки, несоответствие стандартам кода, отсутствие тестов), не обнаруживаемые автоматизированными проверками CI. Защищённые ветки (branch protection) технически запрещают прямой push в основную ветку, требуя прохождения через pull request с обязательным прохождением CI-проверок и/или одобрением code review.
Пример кода
# Типичный рабочий процесс с GitHub Flow — короткоживущая ветка функции
git checkout main
git pull origin main
git checkout -b feature/add-export-to-pdf
# ... разработка, коммиты ...
git push origin feature/add-export-to-pdf
# Далее — создание pull request через веб-интерфейс GitHub/GitLab
# Настройка защиты ветки (концептуально, через GitHub API/UI, не сам YAML-файл репозитория)
# Branch protection rules для ветки main:
# - Require pull request before merging
# - Require status checks to pass before merging (CI должен быть зелёным)
# - Require approvals: 1 (хотя бы один одобривший code review)
# - Restrict who can push to matching branches (прямой push запрещён всем)
# Соглашение об осмысленных, атомарных коммитах — облегчает code review и историю проекта
git commit -m "Добавить экспорт отчёта в PDF через QPdfWriter"
# а не:
git commit -m "fix" # неинформативное сообщение, не объясняющее суть изменения
# Squash merge — объединение множества промежуточных коммитов ветки в один,
# чистый коммит при слиянии в основную ветку (опция при merge через UI)
Пояснения к коду
Рабочий процесс GitHub Flow — короткоживущая ветка feature/add-export-to-pdf, отделённая от main, позволяет вести разработку конкретной функции изолированно, не затрагивая основную ветку до завершения и проверки этой функции, и push в отдельную ветку (а не прямо в main) автоматически запускает CI для этой конкретной ветки (статья 446), позволяя проверить изменения до их попадания в основную ветку. Настройки защиты ветки на уровне платформы (GitHub/GitLab) технически принуждают к соблюдению процесса — даже если разработчик забудет или намеренно попытается обойти процесс code review, технический контроль через защищённые ветки не позволит слияние без прохождения настроенных требований, что значительно надёжнее простого устного соглашения о процессе без технического принуждения к его соблюдению.
Подводные камни
- Слишком сложная модель ветвления (полный Git Flow с множеством долгоживущих веток) для небольшого проекта/команды, где более простой GitHub Flow дал бы тот же результат с меньшей сложностью управления — выбор модели ветвления должен соответствовать реальному масштабу и потребностям команды, и излишне сложная модель для простого проекта создаёт ненужные накладные расходы на управление множеством веток без соразмерной выгоды.
- Настройка защищённых веток без требования прохождения CI-проверок, оставляя лишь требование code review — без автоматизированной проверки прохождения тестов/сборки как обязательного условия слияния, человеческий code review может пропустить проблему, которая была бы автоматически обнаружена CI (особенно для проблем, не очевидных при простом визуальном просмотре изменённого кода, но выявляемых при реальной сборке/тестировании на другой платформе) — защита ветки должна включать оба требования совместно, а не одно из них в отдельности.
- Слишком долгоживущие ветки функций, накапливающие значительные расхождения с основной веткой за длительное время разработки до их слияния — это увеличивает риск сложных, трудноразрешимых конфликтов при попытке слияния, и значительно усложняет сам code review (большой, накопленный за долгое время diff труднее качественно проверить, чем небольшой, частый); практика частых, небольших, быстро слитых изменений (continuous integration в буквальном смысле этого термина) значительно снижает этот риск по сравнению с редкими, крупными слияниями.
- Формальный, поверхностный code review «для галочки» (одобрение без реального, внимательного прочтения изменений) просто чтобы технически пройти требование защищённой ветки — это устраняет реальную пользу процесса review при сохранении лишь формальной видимости его соблюдения, и для эффективного code review важна реальная, осмысленная культура команды, а не только техническое принуждение через настройки защиты веток, которое само по себе не гарантирует качества фактически проводимого review.