Лучшая стратегия ветвления при непрерывной интеграции? - PullRequest
98 голосов
/ 28 февраля 2009

Какую стратегию ветвления лучше всего использовать для непрерывной интеграции?

  1. Ветвь релиза: развивайтесь на стволе, сохраняйте ветвь для каждого выпуска.
  2. Разветвление элемента: Разрабатывайте каждую функцию в отдельной ветви, объединяйте только однажды стабильную.

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

Ответы [ 12 ]

20 голосов
/ 18 марта 2009

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

  • Я помню, как Марк Шаттлворт предложил модель, позволяющую сохранить основную ветвь первозданной, выходя за рамки обычной КИ. Я написал об этом здесь .
  • Поскольку я знаком с круиз-контролем, я также писал о ветвях задач и CI здесь . Это пошаговое руководство, объясняющее, как это сделать с помощью Plastic SCM .
  • Наконец, я нашел некоторые темы о КИ (и, возможно, о ветвлении) в книге Дювалла о КИ тоже очень интересными .

Надеюсь, вы найдете ссылки интересными.

20 голосов
/ 03 марта 2009

Ответ зависит от размера вашей команды и качества вашего исходного контроля и способности правильно объединять сложные наборы изменений. Например, полный контроль над источниками ветвления, такой как CVS или SVN, может быть затруднен, и вам может быть лучше с первой моделью, в то время как если вы используете более сложную систему, такую ​​как IBM ClearCase, и с большим размером команды, то лучше со второй модель или их комбинация.

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

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

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

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

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

9 голосов
/ 28 февраля 2009

Лично мне гораздо чище иметь стабильный ствол и выполнять функции разветвления. Таким образом, тестеры и им подобные остаются на одной «версии» и обновляются из транка, чтобы протестировать любую функцию, которая завершена кодом.

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

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

5 голосов
/ 28 июня 2011

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

http://martinfowler.com/articles/continuousIntegration.html#EveryoneCommitsToTheMainlineEveryDay

EDIT

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

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

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

ДРУГОЕ РЕДАКТИРОВАНИЕ

Существует несколько мнений по этому вопросу. Вот сообщение в блоге, которое про ветвление функции с CI

http://jamesmckay.net/2011/07/why-does-martin-fowler-not-understand-feature-branches/

5 голосов
/ 21 марта 2010

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

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

Так что для меня использование обоих механизмов - очень хорошая стратегия.

Интересная ссылка из Книги СВН .

4 голосов
/ 21 марта 2010

Я недавно полюбил эту модель при использовании git. Хотя ваш вопрос помечен как «svn», вы все равно сможете его использовать.

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

2 голосов
/ 21 марта 2010

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

Сказав это ...

  • нет никаких причин, по которым CI нельзя использовать в обоих описанных вами подходах
  • эти подходы довольно хорошо работают в комбинации
  • ни одна из двух не работает "лучше", чем другая
  • CI имеет смысл с нестабильной магистралью

На все это был дан ответ в четвертом вопросе на странице, с которой вы взяли диаграммы: http://blogs.collab.net/subversion/2007/11/branching-strat/

2 голосов
/ 16 апреля 2009

Пока вы понимаете принципы, вы всегда можете заново изобретать лучшие практики. Если вы не понимаете принципов, лучшие практики перенесут вас намного раньше, чем развалится из-за противоречивого внешнего требования.

Для лучшего знакомства с моделью магистрали, прочитайте это: https://web.archive.org/web/20120304070315/http://oreilly.com/catalog/practicalperforce/chapter/ch07.pdf

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

http://www.infoq.com/articles/agile-version-control

1 голос
/ 22 июня 2011

Когда мы начинали нашу команду, мы унаследовали основанную на выпуске стратегию от поставщика, который первоначально разработал систему, которую мы собирались взять на себя. Это работало до тех пор, пока наши клиенты не потребовали, чтобы несколько разработанных функций не были включены в релиз (например, ~ 250 тыс. Строк кода, ~ 2500 файлов, Scrum с XP SDLC).

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

Последний «гвоздь в гробу» стратегий чистого SC наступил, когда мы решили, что у нас должны быть 1. стабильный ствол и 2. Производство должно содержать проверенные BINARIES (ST, UAT и регрессионные регрессии) (а не только источник - подумайте CC).

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

Итак, у нас есть багажник. Каждый спринт, который мы разветвляем, разветвляет ветвь спринта (для не-гибких людей - спринт - это просто разработка с временными рамками с переменным выводом, зависящим от сложности). Из ветви спринта мы создаем ветви функций, и в них начинается параллельная разработка. Как только функции завершены и система протестирована, и мы получаем намерение развернуть их, они объединяются с веткой спринта - некоторые могут перемещаться по нескольким спринтам, обычно более сложным. Как только спринт подходит к концу и функции завершены ... мы «переименовываем» ветку спринта в «регрессию» (это позволяет CruiseControl подобрать ее без какой-либо реконфигурации), и затем на cc-build начинается тестирование регрессии / интеграции EAR. Когда все это сделано, оно идет в производство.

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

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

0 голосов
/ 22 марта 2019

Дейв Фарли , автор Непрерывная доставка , именуемый Разработка на основе магистрали (TBD) как краеугольный камень непрерывной интеграции (CI) и непрерывной доставки (CD). Он говорит:

Любая форма ветвления противоположна непрерывной интеграции.

Он также говорит,

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

Разработка на основе соединительных линий (TBD) - это практика интеграции изменений кода в соединительную линию (a.k.a, master, mainline), по крайней мере, один раз в день, предпочтительно несколько раз в день. Непрерывная интеграция (CI) является аналогичной практикой, за исключением того, что она также включает проверку изменений кода с использованием автоматических тестов. Лучшая стратегия ветвления для этого состоит в том, чтобы работать непосредственно с внешней линии и выполнять проверку кода с помощью парного программирования . Если по какой-то причине вы не можете создать пару или просто действительно хотите разветвляться, убедитесь, что ваши ветви недолговечны (менее суток).

Я работаю над Trunk, master в моих репозиториях GIT. Я обязуюсь выполнять локальный мастеринг и сразу же, когда я подключен к сети, нажать на мое центральное репо, где работает CI. Вот и все!

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

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

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