Фон
Я работаю в команде, которая стремится внедрить развертывание без простоев. Мы планируем использовать сине-зеленую стратегию развертывания для достижения этой цели. Одна из вещей, которые я осознаю, выполняя исследования, это то, насколько сложно вносить изменения в базу данных. Простая операция, такая как переименование столбца, может занять 3 полных цикла выпуска, пока она не будет завершена!
Мне кажется, что полное развертывание изменения в течение нескольких циклов выпуска может привести к человеческим ошибкам. В связанной статье показано, что изменения кода необходимы для 2 выпусков, а миграция базы данных необходима для 3 выпусков.
Что я ищу
В настоящее время, если мы хотим не забыть что-то сделать, мы можем создать заявку в нашей системе управления проблемами, которая создает беспорядок, а также может быть перенесена руководством на более поздний спринт или отставание; или мы можем создать комментарий TODO, который, вероятно, будет полностью забыт.
То, что я ищу, - это способ, которым комментарий TODO может иметь крайний срок против него, и наша система непрерывной интеграции (текущая неопределенная, которую мы будем использовать) отклонит сборку, если этот срок истек.
Например, если мы переименуем столбец, мы можем создать для него начальную миграцию, а затем два комментария TODO, чтобы убедиться, что оставшиеся две миграции созданы:
// TODO by v55: Create migration to move constraints to new column, remove references to old column in app
// TODO by v56: Create migration to drop old column
Это кажется довольно простым для реализации, но мне интересно, если что-то подобное уже существует, потому что я не хочу заново изобретать колесо.
Дополнительные мысли
Я чувствую, что у меня могут возникнуть проблемы с XY, учитывая, что развертывание и сине-зеленое развертывание считаются наилучшей практикой, и кажется странным, что я не могу найти решение, позволяющее сделать обновления базы данных менее болезненными. Если вы думаете, что я смотрю не совсем правильно, пожалуйста, дайте мне знать в комментарии! Тем не менее, пример базы данных, который я привел, является лишь одним примером, и я думаю, что комментарии TODO с указанием сроков будут полезны и в других ситуациях, поэтому даже если я неправильно подхожу к этой конкретной ситуации, мне бы очень хотелось получить ответы на свои вопросы. актуальный вопрос тоже. Спасибо!
РЕДАКТИРОВАТЬ: я просто подумал о другой ситуации, где это может быть полезно. Если вы используете Feature Toggles для включения частей вашего приложения, когда они будут готовы, вы должны быть осторожны, чтобы очистить их, в противном случае вы можете получить Toggle Debt . Комментарии со сроками могут быть хорошим способом запомнить это.
TODO <Bug#>:
для отслеживания обходных путей для проблем с другими компонентами. Когда ошибка устранена в одном из этих компонентов, вы можете легко найти и устранить соответствующие обходные пути. Он не заменяет систему отслеживания проблем, он облегчает обслуживание.Ответы:
Этот вопрос действительно два вопроса в одном.
Тодо комментарии
Из всех способов отслеживания предметов действий это худший. Комментарии TODO хороши во время активной работы или в качестве предложения для сопровождающего, «вот кое-что, что может быть улучшено в будущем». Но если вы полагаетесь на комментарии TODO для выполнения работы, вы обречены на провал.
Что с этим делать
Комментарии TODO - это, в основном, технический долг, поэтому с ним следует обращаться, как с любым другим техническим долгом. Либо решайте их немедленно, если у вас есть время, либо отложите их в очередь, чтобы их можно было отслеживать и расставлять приоритеты.
Вообще говоря, и это полностью самоуверенно и открыто для обсуждения, комментарии TODO можно считать запахом кода. Если комментарий TODO делает это настолько далеко, насколько его проверяют в управлении версиями, вы должны спросить себя, собираетесь ли вы выполнить его прямо сейчас? Если нет, то все в порядке. Просто будьте честны с собой и оставьте это в отставании.
То, как вы управляете этим отставанием, сводится к бизнес-процессу, политике компании и, возможно, некоторой личной автономии. Но вам все еще нужно отслеживать и расставлять приоритеты, чтобы убедиться в этом.
Изменения базы данных
Да, с изменениями в базе данных сложно работать с политикой без простоев. Некоторые приемы, помогающие сделать его менее болезненным:
Процесс после развертывания
Создайте процесс после развертывания, который выполняется как часть того же выпуска. Однако вы хотите, чтобы это работало. На последней системе, над которой я работал, я разработал 4-фазное развертывание:
Идея состояла в том, чтобы, по возможности, мы вносили как можно больше изменений в базу данных в preapp.
Postapp был зарезервирован для необычных случаев, когда нам нужно было вносить несовместимые изменения схемы. В этих случаях preapp внесет достаточно изменений, чтобы сделать новый код приложения совместимым (возможно, создаст временное представление для совместимости), а postapp очистит любые такие временные артефакты.
Фаза окна обслуживания была зарезервирована для изменений, которые действительно требовали простоев или когда риск или стоимость развертывания в реальном времени не стоили этого. Например, сценариям, которые изменяют большие объемы данных, может потребоваться блокировка всей таблицы.
Развертывание часто
Если вы развертываете новые выпуски достаточно часто, вы можете достичь точки, в которой перенос изменений между двумя или тремя выпусками является тривиальным. Длинные циклы выпуска увеличивают стоимость изменений базы данных.
источник
Не используйте TODO. У вас уже есть список TODO в вашем проекте. Это называется трекер проблем.
Я думаю, что настоящая проблема в этом предложении:
Если ваш трекер проблем создает много беспорядка, найдите способы исправить это. Может быть, особый тип вопроса / тег, который требует меньше церемоний. Возможно подвопросы. Может быть, меньше церемония в целом. Мы не можем действительно сказать. Но если ваше средство отслеживания проблем создает так много работы, что люди скорее формулируют сложный вопрос на публичном форуме, чем просто добавляют этот вопрос, что-то серьезно не так.
Если ваше управление чрезмерно задерживает последнюю часть задачи, у вас есть два варианта:
поговорите со своим руководством, почему это плохая идея.
справиться с этим как с одной задачей. Это может быть решением золотого стандарта. В идеальном мире вы должны быть в состоянии сделать три изменения, необходимые на каждом этапе. Примените один к главной ветке, позвольте ему строить и развертывать. А пока примените второе к основной ветке, позвольте ей строить и развертывать и так далее, чтобы все происходило в одном спринте, а если нет, то это не делается. Может быть, даже что-то автоматическое имеет смысл, когда вы логически делаете одно развертывание, но на самом деле оно разделено на 3.
источник
// TODO(#12345): Frobnicate the sprocket before passing it along
, при условии, что ошибка # 12345 является «реальным» номером проблемы, и проблема назначена кому-то. Это облегчает чтение источника, поясняя: «Нет, шаг frobnicate не скрывается ни в одном из вспомогательных методов, он просто не реализован. Посмотрите на ошибку # 12345 для большего контекста». В идеале, вам бы приходилось ежедневно бегать по кодовой базе в поисках закрытых или недействительных номеров выпусков, конечно.То, о чем вы просите, выполнимо, если вы готовы выполнить работу и выполнить ее.
grep для того,
//TODO by v55
когда пришло время развернуть v55. Развертывание сборки запускает скрипт, который выполняет это как интеграционный тест.Вы можете привязать 55 к вашей версии отслеживания или просто запросить ее.
Будет интересно, если вы захотите проверить // TODO с помощью v54 при выполнении 55. Вместо этого ищите в базе кода 55 раз, просто ищите // TODO по. Затем отфильтруйте этот результат от 1 до 55. Теперь 56 не вызовет сбой.
Вы можете подумать: «О, нам это не понадобится. Мы исправим это каждый раз, пока у нас есть чек». Нет, не будешь.
источник
У нас была очень похожая проблема в нашей команде. Чтобы решить эту проблему, мы написали проверку статического анализа, которая обрабатывает эти TODO, проверяя проблему JIRA или проблему Git, на которую они ссылаются. Наша сборка завершается неудачно, когда указанная проблема проходит мимо столбца «В разработке».
Поэтому мы можем с комфортом иметь TODO, не беспокоясь о том, что о них забудут.
Я создал реализацию этого с открытым исходным кодом в Java. Да, отказ от ответственности заключается в том, что я написал это, но, как я уже сказал, он полностью открыт и имеет лицензию.
Инструмент называется Westie, и пример средства проверки проблем Jira приведен на README.md. Смотрите также GitIssueAnalyser.
Чтобы предотвратить саморекламу, если у вас есть какие-либо дополнительные вопросы, отправьте мне сообщение. Если вы решите использовать его и у вас есть предложения, пожалуйста, поднимите все вопросы на github.
источник
Не делай. Сделай это сейчас.
TLDR: пишите (и тестируйте) ваши сценарии БД сейчас, а не позже; просто закодируйте их, чтобы их выполнение зависело от версии БД.
пример
Например, давайте представим, что вы хотите изменить имя столбца с
SSN
наTaxID
- обычное требование при переходе на международный уровень.Чтобы это произошло, может быть , вы будете временно иметь как
TaxID
иSSN
столбец. И, поддерживая обе версии, у вас будет триггер для обновления одной из другой. Но вы не хотите хранить этот триггер бесконечно, поэтому позже, когда обратная совместимость больше не нужна, вы захотите, чтобы этот триггер был удален (иSSN
столбец был удален ). Мы собираемся закодировать все это без необходимости в элементах ToDo.В нашем примере мы будем развертывать сборку 102 (в которой есть новый столбец), сохраняя совместимость со сборкой 101 (в которой этого нет).
Вот шаги.
1. Настройте таблицу версий
Добавьте одну таблицу
Configuration
с двумя столбцамиName
иValue
.Добавьте строку с параметром
Name
«TargetVersion» и задайтеValue
версию новой развертываемой сборки.Добавьте строку с параметром
Name
«CompatibleWith» и задайтеValue
минимальный номер версии, с которым развертывание должно быть совместимым.Проверяйте и обновляйте эти строки перед каждым развертыванием.
2. Изменить сценарии развертывания
Добавьте сценарий, который создает новый столбец
TaxID
рядомSSN
и заполняет его изSSN
столбца. Включите этот код вIf
оператор, который проверяет TargetVersion; если целевая версия слишком низкая (т.е.TaxID
пока не нужна), пропустите.Добавьте скрипт, который создает триггер, который заполняется
TaxID
при вставке или обновленииSSN
и наоборот. Включите этот код вIf
оператор, который проверяет целевую версию и совместимую версию; пропустите, если TargetVersion слишком низок (TaxID
не нужен) или если версия CompatibleWith слишком высока (SSN
поле не требуется).Добавьте скрипт для удаления
SSN
столбца. Включите вIf
оператор, который удаляет столбец, только если версия CompatibleWith достаточно высока (SSN
больше не нужна).3. Тестирование
Обязательно протестируйте свое развертывание с любой комбинацией синих / зеленых номеров версий, которую вы хотите поддерживать в производстве. Вы можете проверить, как только код будет готов, манипулируя
Configuration
таблицей в вашей среде QA.4. В вашем развертывании playbook
Добавьте шаг для инженера для обновления версии CompatibleWith и строк TargetVersion. Если вы развертываете в Blue, установите TargetVersion в номер версии Blue, а в версии CompatibleWith - номер версии Green; поменяйте их, если вы развертываете Green.
Ловушки
Ваши сценарии развертывания могут ссылаться и ссылаться на номера версий в этой таблице БД. НЕ код выполнения.
Если вы начнете писать свой код времени выполнения для проверки номеров версий, вы вводите новый уровень сложности в ваше приложение, которое потенциально может стать огромной проблемой сопровождения. Каждый путь выполнения во время выполнения должен быть проверен; если вы будете придерживаться этих условий в будущем, QA придется составить матрицу боли, чтобы подтвердить их с каждым выпуском. Мой совет - сохранять условия, подобные этим, только в сценариях развертывания.
Итог всего этого
В конце концов, вы должны быть в состоянии написать весь код заранее (и протестировать его тоже), не опасаясь, что он будет выполняться слишком рано. Кроме того, код будет очищать триггер обратной совместимости, когда придет время, и вам не придется беспокоиться об этом дальше.
Таким образом, вы можете написать и протестировать весь код заранее, когда вы думаете об этом, и вам не нужно иметь дело с этими грязными комментариями ToDo.
источник
Вы получаете большой откат от вашей идеи TODO, но я лично не вижу проблем с этим. В конце концов, лучший (и самый простой) способ убедиться, что миграция переходит в рабочую среду, - это провалить модульное тестирование, если это не так. Буквально у вас уйдет меньше минуты, чтобы заглушить пустую функцию миграции, которая выдает исключение, если версия 55 или больше (или каковы требования).
Затем, если вы попытаетесь выпустить его, вы закончите неудачным тестом, и кто-то должен будет превратить это исключение в реальный код миграции.
источник
Никто, кажется, не сосредотачивается на сути своей жалобы, которая заключается в том, что изменения базы данных могут занять слишком много циклов выпуска. Он хочет продолжить свой сине-зеленый график развертывания, и решение уже должно быть там, но если я что-то упустил, его описание, похоже, указывает на то, что существует только одна база данных, которая используется обеими системами. Не настоящая сине-зеленая система, если это так. Поскольку создается впечатление, что база данных является длинным полюсом в палатке, ее также следует дублировать, чтобы независимо от того, сколько времени или сколько циклов выпуска требуется для реализации изменений базы данных в автономной системе, они не запускаются, пока не будут завершены, и полностью протестирован. Во временной автономной системе скрипты могут ежедневно полностью обновлять автономную базу данных.
источник