Master Branch Must Be Read-Only

The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:

Непрерывная интеграция - это просто. Скачайте Jenkins, установите, создайте задачу, нажмите кнопку и получите приятное письмо, которое говорит о том, что ваша сборка повреждена (я предполагаю, что ваша сборка автоматизирована). Затем исправьте поврежденные тесты (я предполагаю, что у вас есть тесты) и получите гораздо более привлекательное письмо, которое говорит о том, что ваша сборка чиста.

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

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

В конце концов, все мы знаем, что юнит-тестирование не предназначено для команды, работающей под давлением сроков, верно?

Неверно. Непрерывная интеграция может и должна работать.

What is Continuous Integration?

В настоящее время программное обеспечение разрабатывается командами. Мы разрабатываем в отдельных ветках и изолируем изменения во время разработки. Затем мы объединяем ветки в master. После каждого объединения мы тестируем весь продукт, выполняя все доступные модульные и интеграционные тесты. Это называется непрерывной интеграцией (или “CI”).

Иногда некоторые тесты не проходят успешно. Когда это происходит, мы говорим, что наша “сборка сломана”. Такая неудача является положительным побочным эффектом контроля качества, потому что она сразу поднимает красный флаг после того, как ошибка попадает в master.

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

Непрерывная доставка (Continuous Delivery) - Джеф Хамбл и др. идеально объясняет этот подход в главе 7, страницы 169–186.

На рынке есть несколько хороших инструментов, которые автоматизируют процессы DevOps. Некоторые из них являются открытыми и вы можете их скачать и установить на свои собственные серверы. Например: Jenkins, Go и CruiseControl. Некоторые из них доступны как облачные сервисы, такие как: Travis, Shippable, Wercker и многие другие.

Why Continuous Integration Doesn’t Work?

CI хороша, но чем больше команда (и кодовая база), тем чаще сборки ломаются. И чем дольше их восстанавливают. Я видел много случаев, когда трудолюбивая команда начинает игнорировать красные флаги, поднятые Jenkins’ом, после нескольких недель попыток не отставать.

Команда просто становится неспособной исправить все ошибки вовремя. Главным образом, потому что у бизнеса есть другие приоритеты. Владельцы продукта не понимают важности “чистой сборки”, а технические руководители не могут выделить время на исправление модульных тестов. Более того, код, который их сломал, уже находится в master, и в большинстве случаев уже был развернут в продакшн и доставлен конечным пользователям. Какая срочность в исправлении некоторых тестов, если бизнес-ценность уже доставлена?

В конце концов, большинство команд разработчиков не воспринимают предупреждения о непрерывной интеграции всерьез. Для них Jenkins или Travis - это просто модные инструменты, которые не играют роли во всем процессе разработки и доставки. Независимо от того, что говорит сервер непрерывной интеграции, мы все равно доставляем новые функции нашим конечным пользователям. Мы исправим нашу сборку позже. И это только логично.

What Is a Solution?

Четыре года назад, в 2010 году, я опубликовал статью в [phpArchitect](http://www.phparch.com/magazine/2010-2/august/) под названием “Предотвращение конфликтов в распределенных гибких проектах на PHP.” В статье было предложено решение (полная статья в PDF) для Subversion и PHP.

С тех пор я экспериментально применял этот подход в нескольких проектах с открытым исходным кодом и нескольких коммерческих с использованием PHP, Java, Ruby и JavaScript, Git и Subversion. Во всех случаях мой опыт был только положительным, и именно поэтому был создан rultor.com (о нем позже).

Итак, решение простое – запретить кому-либо сливать что-либо в master и создать скрипт, который может быть вызван любым. Скрипт будет сливать, тестировать и фиксировать изменения. Скрипт не будет делать исключений. Если хотя бы один модульный тест не проходит на любой ветке, вся ветка будет отклонена.

Другими словами, нам следует поднять красный флаг до того, как код попадет в master. Мы должны возложить вину за неисправные тесты на автора.

Скажем, я разрабатываю функцию в своей собственной ветке. Я завершил разработку и случайно сломал несколько тестов. Это случается, мы все ошибаемся. Я не могу объединить свои изменения с master. Git просто отклоняет мою push, потому что у меня нет соответствующих прав. Все, что я могу сделать, это вызвать магический скрипт, попросив его объединить мою ветку. Скрипт попытается объединить, но перед тем, как запушить в master, он запустит все тесты. И если какой-либо из них сломается, моя ветка будет отклонена. Мои изменения не будут объединены. Теперь это моя ответственность - исправить их и вызвать скрипт снова.

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

Pre-flight Builds

Некоторые CI-серверы предлагают функцию предварительной сборки, которая означает тестирование веток перед их объединением в master. Например, у Travis есть эта функция, и она очень полезна. Когда вы делаете новый коммит в ветке, Travis сразу же пытается собрать его и сообщает о проблемах в запросе на объединение в GitHub.

Обратите внимание, предварительные сборки перед полетом не объединяются. Они только проверяют, чиста ли ваша отдельная ветка. После объединения она может легко сломать master. И, конечно же, этот механизм не гарантирует, что никакие сотрудники не смогут прямо вносить изменения в master, непреднамеренно его сломав. Предварительные сборки перед полетом являются предупредительной мерой, но не решают проблему полностью.

Rultor.com

Для начала работы, как объяснялось выше, все, что вам нужно сделать, это отозвать права на запись для ветки master (или /trunk в Subversion).

К сожалению, это невозможно на GitHub. Единственное решение - работать только через форки и запросы на объединение изменений. Просто удалите всех из списка “соавторов”, и они будут вынуждены отправлять изменения через запросы на объединение.

Затем начните использовать Rultor.com, который поможет вам тестировать, объединять и отправлять каждый запрос на получение изменений (pull request). В основном, Rultor представляет собой скрипт, о котором мы говорили выше. Он доступен как бесплатный облачный сервис.

пс. Краткая версия этой статьи также опубликована на devops.com

Translated by ChatGPT gpt-3.5-turbo/35 on 2023-09-09 at 06:01

sixnines availability badge   GitHub stars