Как нам избежать CI-ориентированной разработки ...?

45

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

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

В настоящее время наш CI создает ядро ​​и поддерживаемые плагины.

Одна из больших проблем, с которыми мы сталкиваемся, заключается в том, что большинство участников (и особенно случайных) не создают 90% поддерживаемых плагинов, поэтому, когда они предлагают рефакторинг изменений в ядре (что в наши дни происходит довольно регулярно), они проверили, что код компилируется на их машине, перед тем как сделать запрос на GitHub.

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

Этот плагин может зависеть от сторонних библиотек, таких как CUDA, например, и пользователь не хочет, не знает, как или просто не может по аппаратным причинам скомпилировать этот сломанный плагин.

Итак - либо PR остается объявление Aeternam в чистилище никогда-быть-сливались ОР - Или вкладчик отбирает переименованные переменный в источнике разбитого плагина, изменяет код, наталкивает на его / ее филиал, ждем CI для завершения компиляции обычно получает больше ошибок и повторяет процесс до тех пор, пока CI не будет доволен - или один из двух уже перебронированных перманентов в консорциуме протягивает руку и пытается исправить PR на своей машине.

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

lagarkane
источник
84
Самое главное правило предоставления плагина API для системы - она должна быть стабильной или, по крайней мере, обратно совместимой. Изменения в ядре без преднамеренных изменений в API плагинов никогда не должны нарушать компиляцию каких-либо плагинов (может случиться так, что это случайно нарушит функциональность, но не компиляцию). Если простое изменение имени переменной внутри ядра может привести к нарушению компиляции плагина , разделение между плагинами и ядром кажется полностью нарушенным.
Док Браун
«Открытые и опубликованные интерфейсы» Мартина Фаулера могут быть полезны для чтения.
Шверн
1
@KevinKrumwiede: Я уверен, что они уже знают это ;-) Если вы столкнулись с несовместимостью, я уверен, что они намеренно изменили API.
Док Браун
3
Я бы перефразировал вопрос, поскольку он действительно вводит в заблуждение. Что-то вроде того, как я могу управлять PR, когда они нарушают нашу текущую CI? Лучше пойми свою ситуацию, я думаю.
bracco23
2
Насколько сложен / сложен процесс сборки / тестирования? Это просто вопрос запуска одной команды или нажатия одной кнопки. На этом этапе становится разумным ожидать, что пользователи запустят все тесты для себя перед отправкой PR.
Александр

Ответы:

68

CI-управляемая разработка - это хорошо! Это намного лучше, чем не запускать тесты и включать неработающий код! Тем не менее, есть несколько вещей, которые сделают это проще для всех участников:

  • Установить ожидания: иметь документацию для вклада, в которой объясняется, что CI часто обнаруживает дополнительные проблемы и что их необходимо устранить до слияния. Возможно, объясните, что небольшие локальные изменения с большей вероятностью будут работать хорошо, поэтому целесообразно разделить большое изменение на несколько PR.

  • Поощряйте локальное тестирование: упростите настройку тестовой среды для вашей системы. Сценарий, который проверяет, что все зависимости были установлены? Готовый контейнер Docker? Образ виртуальной машины? Есть ли у вашего бегуна механизмы, позволяющие расставлять приоритеты для более важных тестов?

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

  • Разрешите все PR в любом случае: если что-то нельзя объединить, потому что оно сломано, и если нет прогресса в устранении проблем, просто закройте его. Эти заброшенные открытые PR просто загромождают все, и любая обратная связь лучше, чем просто игнорирование проблемы. Можно очень красиво сформулировать это и дать понять, что, конечно, вы будете рады объединиться, когда проблемы будут решены. (см. также: «Искусство закрытия » Джесси Фразелль , « Лучшие практики для сопровождающих : учимся говорить нет» )

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

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

Амон
источник
13
«Эти заброшенные открытые пиарщики просто загромождают все», я бы хотел, чтобы у такого же персонала было такое отношение 😔
GammaGames
34

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

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

Касабланка
источник
20
CI должен иметь автоматизированные тесты. Если вы хотите, чтобы плагины имели одинаковый интерфейс, каждый плагин должен предоставлять тесты, выражающие интерфейс, который им нужен. Приходите к этому таким образом, и когда интерфейс изменится, что будет, вы будете знать, какие плагины вы нарушаете. Дайте мне эти тесты для локального запуска, и я узнаю, что я ломаю, прежде чем выпустить PR.
candied_orange
1
Четкая четкость @lagarkane - это скорее вопрос политики, чем технической. Есть программное обеспечение, которое, как и ваше, просто откажется от предыдущего поведения при обновлении. Perl5 несовместим с Perl6, Python2.7 не полностью совместим с Python3.4 и т. Д. Кроме того, существуют программы, которые, что бы ни случилось, все еще поддерживают старый код. Вы все еще можете запустить почти весь код JavaScript, написанный для Netscape Navigator 4, в современных браузерах. Язык программирования Tcl обратно совместим с обратными словами в исходной версии и т. Д.
slebetman
3
@lagarkane: Создание консорциума было шагом в правильном направлении, и если основные члены сосредоточат свои усилия на создании этих интерфейсов, то вы сможете использовать возможности будущих докторов наук и стажеров, чтобы ваш проект развивался, сводя к минимуму поломки. :)
Касабланка
4
@Fattie: Это работает для Apple, потому что они создают успешные продукты, ориентированные на потребителя, и разработчики вынуждены играть вместе, если они хотят быть частью этого. Маловероятно, что этим разработчикам действительно нравятся критические изменения, и это определенно не очень хорошая модель для проекта с открытым исходным кодом.
Касабланка
1
@casablanca, MacOS и WindowsOS, чрезвычайно успешны. (Возможно, два величайших продукта в долларовом выражении в человеческом существовании.) В течение десятилетий у них были абсолютно противоположные подходы. Видимо оба были успешными!
Толстяк
8

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

Есть ли в вашем проекте что- contributing.mdто подобное или что-то подобное, чтобы помочь новым и случайным авторам подготовить свой вклад? У вас есть четкий список, какие плагины являются частью ядра и должны оставаться совместимыми?

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

MHR
источник
1
Спасибо за ответ! Да, у нас есть общедоступные руководящие принципы, но в них нет списка плагинов, как вы предлагаете, что уже было бы хорошей идеей. Создание изображений в докере звучит как большое улучшение уже существующего процесса! Спасибо за вклад
Лагаркане
8

поэтому, когда они предлагают рефакторинг изменений в ядре (что в наши дни происходит довольно регулярно), они проверяли, что код компилируется на их машине, перед тем как сделать запрос на github.

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

Я хотел бы предложить правило «все изменения API должны планироваться заранее»: если появляется PR, который вносит несовместимые изменения в API от того, кто не связывался с сопровождающими, чтобы заранее согласовать свой подход, он просто закрывается, и податель указывает на правило.

Вам также понадобится явное управление версиями API плагина. Это позволяет вам разрабатывать v2, в то время как все плагины v1 продолжают собираться и работать.

Я также хотел бы задать еще один вопрос: почему так много изменений в рефакторинге ядра и API? Они действительно необходимы или просто люди навязывают свой личный вкус проекту?

pjc50
источник
2

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

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

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

Натан Адамс
источник
2

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

Этот плагин может зависеть от сторонних библиотек, таких как CUDA, например, и пользователь не хочет, не знает, как или просто не может по аппаратным причинам скомпилировать этот сломанный плагин.

Ваше решение простое: снизьте барьер для вклада .

Самый простой способ (1) ускорить цикл редактирования-компиляции-тестирования и (2) сгладить различия в среде - это предоставить серверы сборки :

  • Подберите мощные машины: 24, 48 или 96 ядер, 2 ГБ ОЗУ / ядро, SSD, чтобы ускорить компиляцию.
  • Убедитесь, что у них есть правильное оборудование: FPGA, графическая карта, все, что нужно.
  • Создайте образ Docker со всеми предварительно установленными необходимыми библиотеками программного обеспечения.

А затем откройте эти серверы сборки для участников. Они должны иметь возможность удаленно войти в систему с новым образом Docker и удаленно редактировать-compile-test на этом компьютере.

Затем:

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

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


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

Матье М.
источник
1

Если внесение вклада в ядро ​​без изменения какого-либо контракта может привести к поломке зависимого программного обеспечения, оно предлагает либо:

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

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

jcayzac
источник
1

Никто другой, кажется, не поднял это как потенциальное решение.

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

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

Это не будет на 100% гарантировать совместимость, но это поймает намного больше проблем и рано.

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

Kain0_0
источник
0

У меня проблемы с пониманием ситуации, которая выглядит так: КИ строит только одну ветку?

Есть ли причина, по которой вы не можете построить более одной ветви с помощью CI?

Самое простое решение этой проблемы - дать возможность любому участнику запускать сборку CI в своей ветви функций .

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

Kyralessa
источник
Это кажется, чтобы подвести итог вопроса.
Толстяк
1
Вопрос гласит: «Или [...] участник изменяет код, помещает свою ветку, ждет, пока CI завершит компиляцию, обычно получает больше ошибок и повторяет процесс, пока CI не будет доволен» - так что я думаю, что это уже имеет место, но проблема в том, что с таким длинным циклом редактирования-отладки довольно сложно развиваться.
npostavs
@npostavs Спасибо, я думаю, это то, что я пропустил в первый раз или два, когда я прочитал это. Даже так ... Я думаю, я не вижу проблемы. Существует множество зависимостей, которые не могут быть нарушены, поэтому участник должен оставаться совместимым со всеми из них. Это природа большого программного обеспечения. Конечно, можно было бы поработать над тем, чтобы сделать сборку быстрее, но, в противном случае, какой бы мог быть ярлык?
Kyralessa