Сверхмощная непрерывная поставка с Git

Теперь, когда проблема слияния решена с помощью Git, процессы на основе веток выглядят намного перспективнее.

Sarah Goff-Dupont Sarah Goff-Dupont

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

Совместная работа в команде | Atlassian CI/CD

Но известно и другое: при разработке в команде возможен хаос!

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

Я надеюсь убедить вас в том, что сочетание этих двух подходов дает сверхмощный рецепт успеха. А еще сюда можно добавить разные крутые инструменты (просто ради интереса).

Мощные возможности рабочих процессов на основе веток 

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

Схема базового процесса | Atlassian CI/CD

Конечно Subversion и другие традиционные системы контроля версий тоже позволяют создавать ветки. Но давайте отвлечемся от этого на минуту и подумаем о злом двойнике ветвления: о слиянии.

Традиционные системы контроля версий, например Subversion, не очень хорошо подходят для отслеживания версий файлов, которые располагаются в разных ветках, и когда приходит время слияния, системе Subversion приходится останавливаться и уточнять многие моменты. (Наверняка помните маленькое всплывающее окно, в котором спрашивается: «Эту строку действительно нужно включить в версию после слияния?»...) Тот факт, что во время слияний система требует так много взаимодействия с человеком, заставляет команды вводить запреты на изменение кода, чтобы участника, выполняющего слияние, не сбивали с толку новые изменения, приходящие в какую-либо из веток. А запрет на изменение кода — дорогое удовольствие, так как время при этом расходуется очень непродуктивно.

Git, с другой стороны, отлично подходит для отслеживания изменений разных версий файлов в разных ветках. Система всегда знает, как выглядел общий предок файла. Можно сказать, в Git есть встроенный GPS, который позволяет системе управлять слияниями, не прерываясь и не запрашивая у вас постоянно дальнейших указаний.

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

Хорошо, допустим. Но почему именно создание веток является настолько мощным подходом для непрерывной поставки?

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

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

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

Это также подразумевает использование запросов pull в Git, как формы проверки кода, чтобы вся ваша команда сохраняла уверенность в качестве кода и его надежном взаимодействии с другими участками базы кода. Да, эта работа выполняется гораздо раньше, чем предусмотрено традиционными моделями поставки. И поверьте, результат того стоит.

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

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

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

Ветки позволяют принимать дополнения от людей, не входящих в команду

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

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

Профессиональный совет. Менеджеры репозиториев, такие как Bitbucket, позволяют использовать скрипты Git hook, чтобы обеспечить соответствие стандартам качества. Например, вы можете задать правило, согласно которому запрос pull может быть принят к слиянию только после прохождения сборок всех веток.

Правильное использование веток = четкое отслеживание проекта

Текущий тренд —создавать ветки разработки для всех реализуемых историй, баг‑фиксов и задач (например, задач в Jira). В Atlassian модель, где каждой задаче соответствует отдельная ветка, была внедрена еще пару лет назад, и мы ни разу об этом не пожалели. Она стала популярной и среди наших клиентов.

Создание ветки для каждой задачи позволяет легко выбирать, какие изменения необходимо поставить в рабочую среду или включить в релиз. Поскольку вы не выполняете слияния изменений в главную ветку, у вас есть возможность выбирать, что будет в нее добавлено и когда. Вы можете поставить MVP-версию возможности уровня «эпик» плюс одну возможность из разряда «не помешает», а не ждать, пока будут готовы все подобные возможности. Или же поставить единичное исправление бага, сделав это в рамках обычного релиза. Даже если исправление срочное, вам не придется иметь дело с переполохом, когда нужно отменять другие изменения, не готовые к поставке, только чтобы выпустить то самое исправление.

И в такой легкой поставке одного изменения кода раскрывается сущность непрерывной поставки.

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

Снимок экрана: Bitbucket осуществляет коммит репозитория Git | Atlassian CI/CD

Обратите внимание на принципы наименования, используемые на приведенном выше рисунке: уникальный ключ реализуемой задачи Jira плюс краткое, понятное человеку описание того, о чем эта задача. В результате менеджер по релизам или другая заинтересованная сторона может посмотреть на репозиторий, показанный выше, и сразу понять, что пользовательская история, отслеживаемая по номеру AMKT-13952, готова к релизу: видно, что было выполнено ее слияние с главной веткой. Вот что значит возможность отслеживания без ручного труда — ура!

Как же работает этот процесс на основе Git и непрерывной поставки?

Отличный вопрос! Я расскажу об этом кратко, не вдаваясь в подробности, так как другие статьи на этом сайте углубляются в каждый этап.

  • Создайте ветку для задачи, над которой будете работать. Добавьте ключ задачи Jira в имя ветки, чтобы было понятно, для чего она предназначена. А если вы пользуетесь другими инструментами Atlassian, такими как Bitbucket или Bamboo, они подхватят этот ключ задачи и свяжут между собой задачу, вашу ветку, все ваши коммиты, сборки, запросы pull и развертывания, относящиеся к данной задаче. Короче говоря, ключи задач творят чудеса.
  • Вносите свои изменения в ветке. Это ваш собственный маленький мир, где вы можете делать все что угодно. Пробуйте новое. Ломайте. Это все неважно, потому что следующий пункт…
  • Реализуйте непрерывную интеграцию в своей ветке. (Кстати, Bamboo делает это автоматически.) Здесь вам и вашей команде надо решить, следует ли выполнять специализированные тесты (например, нагрузочные тесты или сквозные тесты на основе пользовательского интерфейса) и нужно ли автоматически запускать прогон тестов каждый раз, когда в ветку вносятся изменения. Команды Atlassian обычно выполняют модульные и интеграционные тесты в ветках разработки и позволяют разработчику выбирать, как часто их запускать, чтобы сберечь ресурсы для сборки и избежать ненужного засорения очереди.
  • Регулярно обновляйте свою ветку, используя последние версии главной ветки. Для этого можно использовать операцию rebase или коммит ветки. Выбирайте на свой вкус. (Только не выполняйте операцию rebase ветки, с которой помимо вас работают другие разработчики — этим вы их сильно рассердите.) В любом случае вы обнаружите конфликты интеграции прежде, чем выполните слияние, что, в свою очередь, поможет поддерживать порядок в главной ветке.
  • Создайте запрос pull, когда будете готовы к слиянию. Это значит, что внедрение завершено, вы осуществили pull изменений от членов вашей команды, устранили все возникшие конфликты, а все тесты в вашей ветке проходят успешно.
  • Постоянное слияние и развертывание по запросу. Некоторые команды предпочитают автоматически поставлять каждое изменение, как только выполнено его слияние в главную ветку и пройдены все тесты. Это модель непрерывного развертывания. Другие команды хотят, чтобы решение о поставке каких-либо изменений и времени такой поставки оставалось за человеком. Выбор только за вами.

Автоматизация CI при использовании Git | Atlassian CI/CD

Вот такая картина. Процессы на основе веток упрощают непрерывную поставку, а Git избавляет от проблем при работе с ветками. Читайте дальше, чтобы глубже погрузиться в настройку репозитория Git для работы с CD и узнать о том, как реализовать все эти идеи на практике с помощью инструментов Atlassian. Увидимся на следующей странице!