Автоматически возвращать коммиты, которые не дают сборки

44

Один мой коллега сказал мне , что он думает , в создании нашего CI сервер , чтобы вернуться фиксаций , которые не строить, так что HEADв masterвсегда устойчиво (как при прохождении сборки по крайней мере).

Это лучшая практика, или она может быть более проблематичной, чем просто masterсломаться, пока разработчик не исправит это?

Я думаю, что отмена коммита усложнит задачу чтения коммита и исправления (разработчик должен будет отменить восстановление, а затем зафиксировать исправление, что также загромождает git log), и мы должны просто оставить коммит и затем зафиксировать фикс. Несмотря на то, что я вижу некоторые преимущества в masterстабильности, этот возврат неудачных коммитов не убеждает меня.

редактирование: не имеет значения, является ли это masterили любая другая ветвь разработки, но вопрос остается тем же: должна ли система CI вернуть коммит, который провалил сборку?

другое (длинное) редактирование: Хорошо, мы используем gitстранным образом. Мы считаем, что концепция ветвей идет вразрез с реальным CI, потому что принятие ветки изолирует вас от других разработчиков и их изменений, а также добавляет время, когда вам нужно реинтегрировать свою ветку и справляться с возможными конфликтами. Если все фиксируют masterэто, конфликты сводятся к минимуму, и каждый коммит проходит все тесты.

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

Есть компромиссы при выполнении КИ тем или иным способом, но это выходит за рамки вопроса (см. Соответствующий вопрос для этого). Если вы предпочитаете, я могу перефразировать вопрос: небольшая команда разработчиков работает вместе в функциональной ветви. Если один разработчик фиксирует что-то, что нарушает сборку для этой ветви, должна ли система CI отменить фиксацию или нет?

Карлос Кампдеррос
источник
38
Неудачные сборки никогда не должны были достигаться masterс самого начала. Для этого используются ветки разработки и функций. Затем эти изменения происходят в чем-то вроде ветки интеграции, где вы можете проверить, будут ли все новые функции нескольких разработчиков работать вместе, и только если они протестированы, они могут перейти в мастер. Или, по крайней мере, это один из возможных рабочих процессов.
Торстен Мюллер
1
@ thorstenmüller хорошо представьте, что все разработчики используют ветку разработки. Должна ли система CI вернуть коммиты, которые потерпели неудачу при сборке?
Карлос Кампдеррос
7
Кажется, вы используете git странным образом. Как правило, люди должны работать над своими собственными репозиториями в своих собственных ветвях, и нажимать на главный сервер только после того, как CI для своей личной сборки подтвердит, что изменения в порядке.
Уилберт
4
> «это конфликты сводятся к минимуму»; Вы получаете меньше конфликтов во время слияния, но вы получаете проблемы с плохими слияниями намного больше. Решение состоит в том, чтобы непрерывно сливаться от мастера к вашей ветви как части вашего процесса, а не к ветке.
deworde
2
... Почему бы не сделать так, чтобы неудачные сборки не принимались в master с самого начала?
user253751

Ответы:

56

Я был бы против этого по следующим причинам:

  • Каждый раз, когда вы настраиваете автоматизированный инструмент для изменения кода от вашего имени , существует риск того, что он получит неправильный код или возникнет ситуация, когда вам потребуется отменить это изменение (например, последняя версия Google Mock). в нем была ошибка, так что это не ошибка вашего кода) и вам придется тратить время на ее перенастройку. Кроме того, всегда есть небольшой риск того, что сборка не удастся из-за ошибки в системе сборки, а не из-за ошибки в вашем коде. Для меня CI - это уверенность в правильности моего кода ; это просто превратило бы меня в еще один источник потенциальных проблем, о которых я мог бы беспокоиться.

  • Ошибки, нарушающие «сборку», должны быть глупыми ошибками, исправление которых занимает очень мало времени (как вы указали в комментарии, это верно для вас). Если на мастер регулярно попадают более тонкие и сложные ошибки, то правильное решение состоит не в том, чтобы «исправить это быстрее», а в том, чтобы быть более осторожным при просмотре ветвей функций, прежде чем они будут объединены.

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

Ixrec
источник
1
Кроме того, только успешные сборки должны вызывать создание «сброса сборки», который может быть развернут. В случае сбоя сборки не должно быть развертываемого сброса сборки, поэтому не должно быть риска, что кто-то опубликует плохой код для клиентов.
Марк Фридман
1
есть определенно другой вариант, который используется и лучше, чем этот, я думаю, и в интенсивном использовании (мы используем его в твиттере). не ставьте неудачные сборки на мастера, и глупые ошибки легко исправить. Смотрите мой полный ответ ниже.
Дин Хиллер,
26

Давайте сначала договоримся об условиях.

Лично я использую термины «Непрерывная сборка» и «Непрерывная интеграция», чтобы различать два разных сценария:

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

Последнее, Непрерывная интеграция, означает, что репозиторий, который он защищает, всегда зеленый 1 : он строго лучше.

Ваш вопрос действительно имеет смысл только для Continuous Build, поэтому я отвечу, если это ваша установка.

1 : Экологические причины также могут испортить сборку, например, тест с жестко запрограммированным годом (2015) может начать проваливаться. Январь 2016 года, диск может быть заполнен, ... И, конечно, существует проблема нестабильности тесты. Я надменно игнорирую эти проблемы здесь; иначе мы никогда никуда не доберемся.


Если у вас есть настройка Continuous Build, вы действительно можете автоматизировать аннулирование коммитов, которые могли нарушить сборку, однако есть несколько тонкостей.

  • Вы не можете фактически лишить коммитов: другие коллеги, возможно, уже проверили их и отодвинут их в следующий раз, когда они попытаются сделать коммит. Вместо этого разворот должен совершать обратный дифференциал. О, и сотрудники будут ненавидеть вас за то, что вы вернули свою работу, когда она была правильной, поскольку им придется найти способ вернуть ее обратно ...
  • Вы не можете фактически удалить только последний коммит (это слияние), но вам нужно удалить все коммиты ... до определенной точки. Например, последний известный удачный коммит (будьте осторожны при загрузке системы).
  • Вам нужно подумать о внешних причинах (проблемах окружающей среды) и избегать установки, которая возвращает все к 0-му дню. К счастью, возврат к последней известной удачной фиксации обходит эту проблему.
  • Вы должны думать, что последняя известная хорошая сборка может больше не собираться (проблемы среды), и в этом случае вполне вероятно, что все дальнейшие коммиты будут отменены. В идеале, в случае сбоя и перед возвратом, вы должны проверить последнюю известную хорошую сборку и повторно протестировать ее. Если это пройдет, отменить, в противном случае, поднять предупреждение.

Обратите внимание, что в этой системе, в случае нестабильного теста или совместной работы сотрудника, часто совершающего дерьмо, многие хорошие коммиты будут отменены. Тогда ваши сотрудники будут ненавидеть вас.


Надеюсь, что мой рассказ ужасов выявил проблемы с разрешением испорченного репозитория, и теперь вы реализуете правильный конвейер непрерывной интеграции, в котором PR никогда напрямую не помещаются в репозиторий, а вместо этого ставятся в очередь для объединения в рабочую очередь и интегрируются по одному ( или по свертке):

  • получить главу хранилища локально
  • применить запрос на выборку
  • построить и проверить
  • в случае успеха нажмите на репозиторий, в противном случае пометьте как неудачный
  • перейти к следующим запросам

Попробовав оба, это строго лучше.

Матье М.
источник
2
Это действительно правильный ответ - правильное решение - не допустить, чтобы плохие изменения когда-либо достигли главной ветви, не позволить им приземлиться, а затем иметь дело с их откатом.
Даниэль Приден
Я думаю, что проблема здесь в том, что спрашивающий считает, что заявленные затраты на «изоляцию вас от других разработчиков и их изменений» перевешивают выгоды. Указанные расходы представляют собой повышенную опасность нетривиальных слияний, если два человека расходятся. ИМО выгода от изоляции от неработающего кода очевидна. Спрашивающий хочет выбрать «оптимистичную» стратегию, в которой кратковременный доступ masterк поврежденному коду доступен для извлечения, а затем исправить эту ситуацию, когда тесты не пройдут. Все остальные используют «пессимистичную» стратегию, как вы советуете, и делают доступным только код, доступный для извлечения.
Стив Джессоп
(где под «доступным для извлечения» я подразумеваю «извлекать из master», что в идеале - это то, что разработчики могут делать волей-неволей, но для этого нужно отложить принятие коммитов masterдо того, как они будут протестированы и пройдены. Если разработчик хочет Вишневый непроверенный или проверенный-и-неудачный код, это тоже хорошо, и код «доступен» в этом смысле, это просто не то, что я имею в виду)
Стив Джессоп
Правильное решение - не допустить, чтобы плохие изменения когда-либо доходили до ЛЮБОЙ ветви. Неудачные коммиты никогда не должны быть обнародованы, никогда.
Майлз Рут
5

Это лучшая практика, или она может быть более проблематичной, чем просто сломать мастер, пока разработчик не исправит это?

Это проблематично. Человек, решающий, что «главный HEAD сломан; я верну главное изменение», полностью отличается от системы CI, делающей то же самое.

Вот несколько недостатков:

  • Ошибки в процессе автоматического обращения испортят хранилище;

  • это предполагает, что один набор изменений (самый верхний) испортил сборку (что нереально)

  • Сопровождающие будут иметь больше работы для решения проблемы, чем просто расследование и фиксация (им также придется взглянуть на обратную историю)

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

Это убеждение (ветви против CI) неверно. Подумайте о том, чтобы сохранить одну стабильную ветвь, в которой вы фиксируете только тестовые наборы, проверенные модулем . Остальные (ветки функций и локальные ветки) должны нести ответственность за каждого разработчика, а не быть частью вашей политики CI.

В тематических ветках вы хотите быть изолированными от других разработчиков. Это позволяет вам:

  • выполнить поисковое кодирование

  • экспериментировать с кодовой базой

  • выполнять частичные коммиты (эффективно коммитить нерабочий код) для настройки точек резервного копирования (на случай, если вы испортите), для создания более значимой истории изменений (с помощью сообщений фиксации), а также для резервного копирования вашей работы и полного переключения на что-то другое ( время, которое требуется для написания "git commit && git checkout")

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

Если один разработчик фиксирует что-то, что нарушает сборку для этой ветви, должна ли система CI отменить фиксацию или нет?

Это не должно За фиксацию стабильного кода в вашей ветви CI отвечает коммиттер, а не автоматизированная система.

utnapistim
источник
2

Я бы предложил использовать среду Gerrit + Jenkins, чтобы ваша ветка master всегда была в хорошей форме. Люди отправляют свой новый код в Gerrit, который запускает задание Jenkins для извлечения этого патча, сборки, тестирования и так далее. Если другим разработчикам понравился ваш патч и Jenkins успешно завершил свою работу, то Gerrit объединит этот фрагмент кода с вашей основной веткой.

Это похожая среда, описанная @ brian-vandenberg

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

[1] Дженкинс https://jenkins-ci.org/

[2] Геррит https://www.gerritcodereview.com/

Густаво Коэльо
источник
1

CI никогда не должен изменять историю коммитов репо.

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

Работаете ли вы над функциональными ветвями, автоматически ли запускается CI на них, и, если сборки терпят неудачу, не объединяйте их в master.

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

Daenyth
источник
1
Это никак не ответит на вопрос. Если сборка не удалась в ветви функций, должен ли CI отменить фиксацию?
Карлос Кампдеррос
Что, если сборка завершится успешно в ветви функций, но завершится неудачно после объединения?
Матье М.
@MatthieuM. слияние - это коммит, должен ли шаг CI, сливающийся, вернуть сборку?
Карлос Кампдеррос
@ CarlosCampderrós: ​​лично у меня никогда не было бы установки, которая пытается вернуть коммиты; слишком сложно.
Матье М.
Я обратился к комментариям.
Дениф
1

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

Коммиты косвенно проталкиваются через завиток в Jenkins, где он клонирует мастер репо, затем извлекает коммит (ы) для объединения и выполняет все необходимые сборки (для Linux / solaris). Если все сборки завершены, коммит подталкивается.

Это позволяет избежать многих, если не всех проблем, которые обсуждались до сих пор:

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

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

Брайан Ванденберг
источник
re: downvote, не могли бы вы прокомментировать то, что вам не понравилось в моем ответе?
Брайан Ванденберг
0

Сколько раз вы получали это автоматическое письмо, в котором говорилось, что ваш последний коммит нарушил сборку? Сколько раз это неправильно? Но теперь вам нужно проверить, действительно ли это был вы или кто-то еще, кто сделал еще один коммит в то же время. Или, может быть, это было что-то экологическое.

Если система не знает наверняка, то я, конечно, не хочу ее автоматизировать.

Мохер
источник
0

Заданный вопрос ошибочен. Я уважаю это заявление, хотя

«Мы считаем, что концепция ветвей идет вразрез с реальным CI, потому что принятие ветки изолирует вас от других разработчиков и их изменений»

Что вы должны делать, хотя эти шаги

  • отработайте мастера, если хотите (это нормально и продолжайте извлекать изменения у всех), НО НЕ БУДЬТЕ заниматься мастером локально
  • ПРОСТО, ДО того, как вы собираетесь зафиксировать свои изменения в master, создайте ветку с submit_XXXXXX
  • пусть ваша автоматическая сборка соберет все ветки submit_XXX
  • Вариант 1: построить разрывы или объединить разрывы ... изменение отклонено, и оно никогда не попадает на мастер
  • Вариант 2: сборка работает, Дженкинс толкает мастера и обновляет его

ПОТОМ то, что мы делаем, это ставим ловушку git commit для предотвращения того, чтобы КАЖДЫЙ из них действительно совершал мастеринг. Он отлично работает .... НИКАКИХ неработающих сборок и НИКАКИХ возвращающихся коммитов от мастера тоже.

позже, Дин

Дин Хиллер
источник