it-swarm.com.ru

Лучшая стратегия ветвления при непрерывной интеграции?

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

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

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

99
KingNestor

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

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

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

20
pablo

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

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

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

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

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

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

20
Jiri Klouda

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

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

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

9
Adnan

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

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

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

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

5
SirFabel

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

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

Правка

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

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

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

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

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

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

5
Phil Hale

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

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

4
hermannloose

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

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

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

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

2
zvolkov

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

Было сказано, что ...

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

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

2
Zac Thompson

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

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

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

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

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

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

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

1
XAvatar

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

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

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

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

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

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

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

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

0
Yani

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

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

ps Где вы взяли эти подходы? - не чувствую, что эти графики представляют все варианты

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

0
eglasius