Начиная с версии 1.0, версии Django нумеруются следующим образом:
Номер версии выглядит как A.B или A.B.C.
A - мажорный номер версии, который увеличивается только при существенных изменениях, которые не совместимы с предыдущими релизами. Так, например, код для Django 1.6 может не запуститься под Django 2.0.
B - минорный номер версии, который увеличивается при большом объёме изменений, совместимых с предыдущими релизами. Код для Django 1.6 будет продолжать работать и под Django 1.7; исключения описаны в замечаниях к релизам.
C - микро номер версии, который увеличивается по мере выпусков баг-фиксов. Он на 100% совместим с предыдущим выпуском, за исключением тех случаев, когда исправление безопасности невозможно без ёё нарушения. В любом случае это указано в замечании к релизу, в котором также приводятся рекомендации для обновления.
Перед выпуском минорного релиза мы готовим альфа, бета и RC версии. Они обозначаются как A.B alpha/beta/rc N, где Nth - альфа/бета/rc версия A.B.
В git каждый релиз Django имеет свой тег, определяющий его номер, подписаный ключом. Также в репозитории каждый релиз находится в отдельной ветке под названием stable/A.B.x, а багфиксы выпускаются на основании уже этой ветки.
Подробнее о том, как подготавливаются релизы безопасности можно прочитать в our security policies.
Мажорные релизы (1.0, 2.0...) очень редки и отражают серьёзные изменения в Django.
Минорные релизы (1.5, 1.6...) выходят каждые 9 месяцев согласно `release process`_. В них добавляются новые возможности, всяческие улучшения и пр.
В минорных релизах некоторые функции могут быть объявлены устаревшими. Если какая-то функциональность объявлена устаревшей в A.B, она будет работать в A.B, в A.B+1 вызывать исключение, а в A.B+2 уже удалена.
Так, например, если мы объявили функциональность устаревшей в Django 1.5:
В Django 1.5 будет добавлена обратная совместимость, вызывающая PendingDeprecationWarning. Исключения этого типа по умолчанию не отображаются, но вы можете их включить, запустив Python с опцией -Wd.
В Django 1.6 будет добавлена обратная совместимость, вызывающая полноправное исключение DeprecationWarning. Это предупреждение достаточно громкое, чтобы начать вас раздражать.
В Django 1.7 функциональность будет удалена.
Микрорелизы (1.5.1, 1.6.2, 1.6.1...) будут выпускаться по мере надобности, зачастую исправляя ошибки в безопасности.
Эти релизы на 100% совместимы с минорными версиями, если это не противоречит вопросам безопасности. Так что вы всегда можете обновляться без сомнений.
В любой момент разработчики Django в той или иной степени поддерживают ряд релизов:
Все новые возможности, а также рефакторинг и исправление ошибок, будут внесены в текущую ветку разработки.
Патчи, применяемые к основной ветке разработки, портируются в последний минорный релиз, порождая следующий микрорелиз, который исправляет следующие проблемы:
Вопросы безопасности.
Ошибки, ведущие к потере данных.
Падения приложения.
Опасные ошибки в новой функциональности.
Согласно правилам, исправления будут портированы в последний минорный релиз, если ошибка является блокирующей дальнейшую разработку.
Исправления безопасности применяются к текущему релизу, а также к двум предыдущим минорным.
Комиттер в праве выбирать какие исправления должны быть в ранних версиях, однако это не должно поломать обратную совместимость.
Исправления документации очень часто переносятся в ветку последнего релиза. Происходит это потому что выгодно иметь свежую и правильную документацию последнего выпуска, а риск проявления регрессии ничтожно мал.
Рассмотрим конкретный пример, когда мы находимся на полпути от Django 1.6 к Django 1.7:
Новая функциональность добавляется в master-ветку разработки Django 1.7.
Исправление критических ошибок будет применено к ветке stable/1.6.x и выпущено под версиями 1.6.1, 1.6.2...
Исправления безопасности будет применено к веткам master, stable/1.6.x и stable/1.5.x. Это послужит поводом к выпуску 1.6.1, 1.5.1 и др.
Исправления документации будет применено к текущей ветке и, если это не трудно, к 1.6.x. Вместе с ними могут перенести также исправления некоторых ошибок.
У Django есть расписание выпуска минорных (1.6, 1.7...) релизов, согласно которому это происходит каждые 9 месяцев или больше в зависимости от новой функциональности.
После каждого релиза происходит несколько недель затишья, в течении которых разработчики ядра готовят план и дорожную карту для следующего релиза. Большинство изменений укладываются в 6-9 месяцев, но из-за некоторых больших работ эти сроки могут увеличиться.
Каждый цикл разделён на 3 периода, которые примерно равны по времени:
Сначала согласовывают список нововведений, которые появятся в следующем релизе. Проводится большой объём предварительных работ по определению действительно необходимой функциональности.
В конце концов разработчики ядра предлагают такой список, который разделён на следующие категории:
“Must-have”: критическая функциональность, без которой релиз не выйдет
“Maybe”: работа по этим пунктам может быть перенесена на потом.
“Not going to happen”: работа по этим пунктам будет перенесена на потом.
Anything that hasn’t got at least some work done by the end of the first third isn’t eligible for the next release; a design alone isn’t sufficient.
Вторая треть времени посвящена непосредственно работе согласно дорожной карте, которая была разработана на первом шаге.
Увеличение времени выхода как правило связано именно с этой фазой.
В конце второй фазы незавершённые “maybe”-фичи будут перенесены в следующий релиз. Функциональность из списка “must-have” является обязательной, что может увеличить время выхода релиза.
Результатом разработки становится создание ветки stable/A.B.x, которая отделяется от master.
Последняя треть цикла тратится на исправление ошибок - никакая новая функциональность более не принимается. Мы стараемся выпустить бета-версию через месяц, а RC спустя ещё один.
Выпуск RC замораживает строковые константы, это случается как минимум за 2 недели до выпуска релиза. После этого новые переводы строк не принимаются.
В течении этой фазы разработчики становятся всё более консервативными в применении патчей, чтобы избежать регрессии. После выпуска RC принимаются только исправления блокирующих ошибок и документации.
В это же время в ветке master может начать появляться новая функциональность, которая будет рассмотрена в цикле релиза A.B+1.
После выпуска нового минорного релиза (например, 1.6), предыдущий переводится в состояние принятия исправлений.
Ветка для исправлений будет расти от stable/1.5.x. Критические ошибки, исправленные в основной ветке, также должны быть исправлены в таких ветках для исправлений. Разработчик, который исправляет ошибку в основной ветке ответственен за портирование патча во все другие.
Давайте рассмотрим гипотетический пример того, как же всё это работает. Предположим, что мы находимся на полпути от 1.5 до 1.6. В этом случае разработка будет вестись в куче мест:
В основной ветке, где ведётся разработка 1.6. Там появляются дополнения, исправления ошибок, и пр., так что ветка обновляется каждый день.
В ветке stable/1.5.x, если в релизе 1.5 обнаружены критические ошибки. Это породит выпуск “1.5.1”, “1.5.2” и так далее.
В ветке stable/1.4.x будут появляться только исправления безопасности под названиями “1.4.2”, “1.4.3” и так далее.
Разработка новой функциональности ведётся в своей ветке. Они будут объединены в master перед выпуском “1.6 alpha 1”.
Mar 30, 2016