Continuous Integration is Dead

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

Несколько дней назад моя статья «Почему непрерывная интеграция не работает» была опубликована на DevOps.com. Почти в тот же день я получил несколько крайне отрицательных критик в Twitter.

Вот мой ответ на не задававшийся вопрос:

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

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

Кстати, мой опыт включает в себя пять лет использования Apache Continuum, Hudson, CruiseControl и Jenkins в более чем 50 открытых и коммерческих проектах. Кроме того, несколько лет назад я создал сервис непрерывной интеграции под названием fazend.com, который был переименован в rultor.com в 2013 году. В настоящее время я также активно использую Travis и AppVeyor.

How Continuous Integration Should Work

Идея проста и очевидна. Каждый раз, когда вы создаете новый коммит в ветке master (или /trunk в Subversion), сервер непрерывной интеграции (или сервис) пытается построить весь продукт. “Построение” означает компиляцию, модульное тестирование, интеграционное тестирование, анализ качества и т. д.

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

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

Давайте рассмотрим организационную сторону.

Непрерывная интеграция - это не только сервер, который строит, но и процесс управления/организации, который должен “работать”. Быть процессом, который работает, означает то, что Джез Хамбл сказал в Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation, на странице 55:

Главное, если процесс сборки не удался, команда разработчиков немедленно приостанавливает все текущие задачи и исправляет проблему.

Это то, что не работает и не может работать.

Who Needs This?

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

Теперь мой вопрос: кто из активно работающей команды может в этом нуждаться?

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

Кому нравится эта непрерывная интеграция и кому она нужна?

Nobody.

What Happens In Reality?

Я могу сказать вам точно. Я видел это множество раз. Сценарий всегда одинаковый. Мы просто начинаем игнорировать состояние сборки непрерывной интеграции. Либо сборка чистая, либо сломанная, и мы продолжаем делать то, что делали раньше.

Мы не останавливаемся и не исправляем это, как рекомендует Джез Хамбл.

Вместо этого мы игнорируем информацию, поступающую от сервера непрерывной интеграции.

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

What About Discipline?

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

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

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

В результате вы получаете много временного кода, написанного кем-то, но никогда не зафиксированного в master, из-за этого фактора страха.

OK, What Is The Solution?

Я уже писал об этом; это называется “read-only” основная ветвь.

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

Другими словами: поднимите красный флаг до того, как код попадет в master.

Это решает все проблемы.

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

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

Кстати, попробуйте использовать rultor.com, чтобы обеспечить принцип “read-only” основной ветви в вашем проекте.

Translated by ChatGPT gpt-3.5-turbo/36 on 2023-10-01 at 08:08

sixnines availability badge   GitHub stars