Обработка нескольких ветвей в непрерывной интеграции

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

До сих пор я обнаружил, что есть два основных подхода, которые я могу предпринять (или, может быть, некоторые другие???).

  • Несколько заданий (говоря о Дженкинсе/Хадсоне здесь) за каждую ветку
  • Множество заданий на две ветки (dev и stable)
    • Управляйте двумя наборами вручную (если вы измените конфиг задания, то обязательно измените его в другой ветке)
      • PITA, но по крайней мере так мало, чтобы управлять
    • Другие дополнительные ветки не получат полный набор тестов, прежде чем они будут перенаправлены на dev
    • Неудовлетворенные разработчики. Почему разработчик должен заботиться о проблемах масштабирования CI. У него простой запрос, когда я вхожу в ветку, я бы хотел проверить свой код. Простой.

Итак, кажется, что если я хочу предоставить разработчикам CI для своих собственных ветвей, мне нужен специальный инструмент для Jenkins (API или shellscripts или что-то?) и масштабирование ручек. Или я могу сказать им, чтобы они чаще сливались с DEV и жили без CI в пользовательских ветких. Какой из них вы бы взяли или есть другие варианты?

Ответ 1

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

Выполнение реального CI означает, что все ваши разработчики регулярно переходят на основную линию. Легко сказать, но тяжелая часть делает это, не нарушая ваше приложение. Я настоятельно рекомендую вам посмотреть Непрерывная доставка, особенно раздел "Сохранение вашего приложения" в главе 13 "Управление компонентами и зависимостями". Основные моменты:

  • Скрыть новую функциональность до ее завершения (A.K.A Функция Toggles).
  • Сделайте все изменения инкрементально в виде серии небольших изменений, каждая из которых может быть освобождена.
  • Используйте ветку с помощью абстракции для внесения крупномасштабных изменений в кодовую базу.
  • Используйте компоненты для развязки частей приложения, которые меняются с разной скоростью.

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

  • Создайте абстракцию над той частью системы, которую необходимо изменить.
  • Реализовать остальную часть системы для использования слоя абстракции.
  • Создайте новую реализацию, которая не является частью пути производственного кода до завершения.
  • Обновите свой уровень абстракции, чтобы делегировать вашу новую реализацию.
  • Удалите старую реализацию.
  • Удалите слой абстракции, если он больше не подходит.

Следующий абзац из раздела "Ветки, потоки и непрерывная интеграция" главы 14: "Расширенная версия контроля" суммирует воздействия.

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

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

Ответ 2

Я бы установил отдельные задания для каждой ветки. Я делал это раньше, и нетрудно управлять и настраивать, если вы правильно настроили Хадсона/Дженкинса. Быстрый способ создания нескольких заданий состоит в том, чтобы скопировать из существующего задания, имеющего аналогичные требования, и изменить его по мере необходимости. Я не уверен, что вы хотите, чтобы каждый разработчик настраивал свои собственные рабочие места для своих веток, но для одного человека (т.е. Менеджера сборки) не так много работы. После того, как пользовательские ветки были объединены в стабильные ветки, соответствующие задания могут быть удалены, когда они больше не нужны.

Если вас беспокоит загрузка CI-сервера, вы можете настроить отдельные экземпляры CI или даже отдельных подчиненных устройств, чтобы помочь сбалансировать нагрузку на несколько серверов. Убедитесь, что сервер, на котором запущен Hudson/Jenkins, является адекватным. Я использовал Apache Tomcat и просто должен был убедиться, что у него достаточно памяти и мощности обработки для обработки очереди сборки.

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

Ответ 3

Я бы выбрал dev + стабильные ветки. И если вы все еще хотите настраивать ветки и боитесь загрузки, то почему бы не перенести эти пользовательские в облако и позволить самим разработчикам управлять ими, например. http://cloudbees.com/dev.cb Это компания, где сейчас Кохсуке. Также есть инструмент Eclipse Tooling, поэтому, если вы находитесь на Eclipse, он будет тесно интегрирован прямо в dev env.

Ответ 4

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

  • создать отдельные хранилища мгновенного снимка в разделе "Связь" для каждой ветки функций.
  • обмениваться локальными репозиториями на специализированных ведомых устройствах
  • использовать репозиторий-сервер-плагин с восходящими репозиториями
  • построить все в рамках одного задания с одним приватным репозиторием

На самом деле последнее решение является наиболее перспективным. Все другие решения не имеют ни того или иного пути. Вместе с плагином job-dsl легко настроить новую ветвь функции. просто скопируйте и вставьте groovy script, адаптируйте ветки и дайте заданию семени создавать новые задания. Убедитесь, что семенное задание удаляет неуправляемые задания. Затем вы можете легко масштабировать с помощью ветвей функций по различным проектам maven.

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

мои 2 цента