Когда следует обновлять зависимости?

30

У нас было два основных кризиса, связанных с зависимостями, с двумя разными базами кода (Android и веб-приложение Node.js). Для репозитория Android необходимо было перейти с Flurry на Firebase, что потребовало обновления библиотеки Google Play Services четырех основных версий. Аналогичная ситуация произошла с нашим приложением Node, размещенным на Heroku, где наш производственный стек (кедр) устарел и его необходимо обновить до cedar-14. Наша база данных PostgreSQL также должна была обновиться с 9.2 до 9.6.

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

Очевидно, что сидеть два года слишком долго. Технология быстро развивается, особенно когда вы используете провайдера платформы, такого как Heroku. Давайте предположим, что у нас есть полноценный набор тестов и процесс CI, такой как Travis CI, который отнимает много догадок при обновлении. Например, если функция была удалена после обновления, и вы использовали ее, ваши тесты не пройдут.

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

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

Крис Сирефице
источник

Ответы:

32

Обычно вы должны обновлять зависимости, когда:

  1. Требуется
  2. Там есть преимущество, чтобы сделать это
  3. Не делать это невыгодно

(Они не являются взаимоисключающими.)

Мотивация 1 («когда надо») - самый срочный водитель. Некоторые компоненты или платформы, от которых вы зависите (например, Heroku), требуют этого, и вы должны встать в очередь. Необходимые обновления часто каскадируются из других вариантов; вы решили обновить до версии PostgreSQL и так далее. Теперь вам нужно обновить драйверы, версию ORM и т. Д.

Обновление, потому что вы или ваша команда чувствуете преимущество в этом, более мягкое и необязательное. Это скорее призыв к суждению: «Стоит ли новая функция, способность, производительность ... стоит усилий и внесения дислокации?» В Olden Times был сильный уклон против необязательных обновлений. Они были ручными и тяжелыми, не было хороших способов попробовать их в песочницеили виртуальную среду, или откатить обновление, если оно не сработало, и не было быстрых автоматических тестов, чтобы подтвердить, что обновления не «расстроили корзину Apple». В настоящее время уклон к более быстрым, более агрессивным циклам обновления. Гибкие методы любят пробовать вещи; автоматизированные установщики, менеджеры зависимостей и репозитории делают процесс установки быстрым и зачастую практически незаметным; виртуальные среды и повсеместный контроль версий упрощают переходы, разветвления и откаты; и автоматическое тестирование позволяет нам попробовать обновление, а затем легко и качественно оценить: «Это сработало? Смещение сместилось оптом: с «если не сломано, не исправляйте» на «рано обновлять, часто обновлять»

Мотивация 3 самая мягкая. Пользовательские истории не занимаются «слесарным делом» и никогда не упоминают «и держат инфраструктуру не более, чем N выпусков позади текущей». Недостатки дрейфа версий (грубо говоря, технический долг, связанный с отставанием от кривой) бесшумно вторгаются, а затем часто заявляют о себе через поломку. «Извините, этот API больше не поддерживается!» Даже в Agile командах может быть сложно мотивировать инкрементализм и «оставаться на вершине» свежести компонентов, когда они не рассматриваются как решающие для завершения данного спринта или выпуска. Если никто не выступает за обновления, они могут остаться без внимания. Это колесо может не скрипеть, пока оно не будет готово к поломке или даже пока оно не сломалось.

С практической точки зрения, ваша команда должна уделять больше внимания проблеме дрейфа версий. 2 года это слишком долго. Там нет магии. Это просто вопрос «заплати мне сейчас или заплати мне позже». Либо решайте проблему смещения версии постепенно, либо страдайте, а затем преодолевайте большие толчки каждые несколько лет. Я предпочитаю инкрементализм, потому что некоторые толчки платформы огромны. Ключевой API или платформа, от которой вы больше не работаете, могут испортить вам день, неделю или месяц. Мне нравится оценивать свежесть компонентов как минимум 1-2 раза в год. Вы можете явным образом запланировать проверки или позволить их запускать относительно метрономическими, обычно ежегодными циклами обновления основных компонентов, таких как Python, PostgreSQL и node.js. Если обновления компонентов не вызывают у вашей команды сильную реакцию, проверка свежести основных выпусков, на плато природного проекта, или каждый k релизов также может работать. Все, что привлекает внимание к исправлению версии, дрейфует на более регулярной каденции.

Джонатан Юнис
источник
5

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

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

Если бы вы обновляли свои зависимости во времени, чтобы «не было головной боли сейчас», вам пришлось бы потратить много рабочего времени (кодирование), чтобы не было возвращаемого значения. И когда вы должны были сделать последнее обновление (то, которое вы делаете сейчас, но обновляете 1 основную версию вместо 4), у вас, вероятно, все равно будет где-то болеть голова (в конце концов, основная версия означает прерывание изменений). Поэтому я думаю, что вы на правильном пути.

Однако, если вам слишком сложно выполнить миграцию и вам приходится много заниматься рефакторингом, скорее всего, проблема заключается в вашей кодовой базе. Для проектов Android характерно не иметь общей архитектуры с точки зрения структуры кода. Хорошая структура внедрения зависимостей, такая как Dagger 2 , и пара принципов разработки программного обеспечения, таких как SOLID , облегчили бы изменение реализации кода при сохранении того же поведения / требований.

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

Кристофер Франциско
источник
4

Если вы используете инструменты управления пакетами (например, npm, NuGet) и имеете комплексный автоматизированный набор тестов, то обновление зависимостей должно быть простым делом, просто обновите пакет, запустите свой набор тестов и посмотрите, есть ли какие-либо проблемы. Если есть, то откат и поднять рабочий элемент, чтобы исследовать и устранить проблему.

Пока стоимость обновления зависимостей низка, ее стоит поддерживать в актуальном состоянии:

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

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

Джастин
источник
2

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

То есть, если вы используете V1 и он все еще поддерживается, вы все равно можете использовать последнюю версию v1.

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

A: Вы еще не выпустили релиз.

B: Вы были на v1 так долго, что он больше не поддерживается

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

Если выходит новая версия вашей зависимости, вы также должны сделать релиз

Ewan
источник
1

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

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

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

Matt
источник
0

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

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

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

Лукас
источник
Я согласен, что каждое обновление должно быть хорошо понято. И это нормально иметь технический долг, если вы можете его погасить. Мы не нанимаемся для того, чтобы быть в последней версии (и только гоняемся за последними версиями все время, без раздумий или анализа), но последние версии могут помочь в том, что нас нанимают.
геоосис