Сверхмощная непрерывная поставка с 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. Накладные расходы, связанные с ветвлением и слиянием, настолько незначительны, что создавать ветки, существующие лишь день или два, становится не только возможно, но и полезно.

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

Branches keep main clean and releasable

We've established that short-lived branches provide a great way for developers to collaborate on a project or feature without stepping on each other’s toes. But more importantly for CD, isolating all the work in progress on development branches keeps main and any stable version branches in a clean state so you can ship at will.

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

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

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

By way of example, all the development teams at Atlassian have an agreement that nothing is ever committed directly to main or the stable branches. Everyone does their work on branches. In fact, we're so bullish on branching that we've taken to creating a separate branch for each Jira issue we tackle – more on that in a bit.

Anyway, this means that people can break as many tests and do as much damage on their branches as they want! Main remains in a state where we can release from it, and where you can make new branches off it without inheriting a bunch of broken code. That's a win for CD and general developer productivity (not to mention morale).

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

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

Here again, rigorous automated testing on their branches or forked repos is the key to collaboration happiness. You'll want to review their build and test results before approving any merges into your main code line.

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

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

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

Creating a branch for each issue makes it easy to hand-pick which changes to ship out to production or bundle into a release. Since you're not dog-piling changes onto main, you get to select what comes into main – and when. You can ship an epic's MVP plus one nice-to-have, rather than wait until all the nice-to-haves are fully baked. Or ship a single bug fix, and do it within the framework of a regular ol' release. Even if the fix is urgent, you won't have to deal with the 3-ring circus of backing out other changes that aren't ready to ship yet just to get that one change out the door.

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

Not only does this approach keep un-proven code off main, when you include the relevant Jira issue key and developer's name or initials in the branch's name, it's crystal clear what the state of development is for each issue in flight.

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

Notice the naming convention used in the picture above: it's the unique key for the JIRA issue being implemented, plus a short, human-readable description of what that issue is all about. So as a release manager or other stakeholder, you could look at the repo shown above and know at a glance that the user story tracked by AMKT-13952 is ready for release because you can see that it's been merged to main. That's traceability without all the manual effort – boom.

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

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

  • Создайте ветку для задачи, над которой будете работать. Добавьте ключ задачи Jira в имя ветки, чтобы было понятно, для чего она предназначена. А если вы пользуетесь другими инструментами Atlassian, такими как Bitbucket или Bamboo, они подхватят этот ключ задачи и свяжут между собой задачу, вашу ветку, все ваши коммиты, сборки, запросы pull и развертывания, относящиеся к данной задаче. Короче говоря, ключи задач творят чудеса.
  • Вносите свои изменения в ветке. Это ваш собственный маленький мир, где вы можете делать все что угодно. Пробуйте новое. Ломайте. Это все неважно, потому что следующий пункт…
  • Реализуйте непрерывную интеграцию в своей ветке. (Кстати, Bamboo делает это автоматически.) Здесь вам и вашей команде надо решить, следует ли выполнять специализированные тесты (например, нагрузочные тесты или сквозные тесты на основе пользовательского интерфейса) и нужно ли автоматически запускать прогон тестов каждый раз, когда в ветку вносятся изменения. Команды Atlassian обычно выполняют модульные и интеграционные тесты в ветках разработки и позволяют разработчику выбирать, как часто их запускать, чтобы сберечь ресурсы для сборки и избежать ненужного засорения очереди.
  • Update your branch with the latest from main frequently. You can use rebase or branch-commit to accomplish this. Totally up to you. (But remember not to rebase a branch that you share with other devs – this will make them grumpy.) Either way, you'll discover integration conflicts before you merge up, which in turn helps keep main clean.
  • Создайте запрос pull, когда будете готовы к слиянию. Это значит, что внедрение завершено, вы осуществили pull изменений от членов вашей команды, устранили все возникшие конфликты, а все тесты в вашей ветке проходят успешно.
  • Merge up, and deploy at will. Some teams prefer to automatically ship each change as soon as it's merged to main and all the tests pass there – the continuous deployment model. Other teams prefer to make a human decision about which changes to ship, and when. It's up to you and your team.

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

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