Как формируется Django?

Этот документ объясняет, как выпустить Django.

Пожалуйста, обновляйте эти инструкции, если вы вносите изменения!**Смысл здесь в том, чтобы быть описательным, а не предписывающим, поэтому не стесняйтесь упрощать или вносить другие изменения, но **обновляйте этот документ соответствующим образом!

Быстрый обзор

Существует три типа релизов, которые вам могут понадобиться:

  • Релизы безопасности: раскрытие и устранение уязвимости. Как правило, это два или три одновременных релиза - например, 3.2.x, 4.0.x и, в зависимости от сроков, возможно, 4.1.x.
  • Регулярные выпуски версий: либо финальный релиз (например, 4.1), либо обновление с исправлением ошибок (например, 4.1.1).
  • Предварительные версии: например, 4.2 alpha, beta или rc.

Краткая версия действий такова:

  1. Если это релиз безопасности, предварительно оповестите список рассылки безопасности за неделю до фактического релиза.
  2. Вычитайте примечания к выпуску, ищите организационные и письменные ошибки. Составьте проект сообщения в блоге и объявления по электронной почте.
  3. Обновление номеров версий и создание пакета(ов) релиза.
  4. Загрузите пакет(ы) на сервер djangoproject.com.
  5. Проверьте подписи пакетов, убедитесь, что они могут быть установлены, и обеспечьте минимальную функциональность.
  6. Загрузите новую версию(и) в PyPI.
  7. Объявите новую версию в админке на djangoproject.com.
  8. Опубликуйте запись в блоге и разошлите объявления по электронной почте.
  9. Обновление номеров версий после выпуска.

Подробностей очень много, поэтому читайте дальше.

Пререквизиты

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

  • Ключ GPG. Если ключ, который вы хотите использовать, не является вашим ключом подписи по умолчанию, вам нужно добавить -u you@example.com к каждой команде подписи GPG, приведенной ниже, где you@example.com - это адрес электронной почты, связанный с ключом, который вы хотите использовать. Также необходимо добавить -i you@example.com к вызову twine.

  • Установка некоторых необходимых пакетов Python:

    $ python -m pip install wheel twine
    
  • Доступ к проекту Django на PyPI. Создайте токен с привязкой к проекту, следуя official documentation, и настройте свой файл $HOME/.pypirc следующим образом:

    ~/.pypirc
    [distutils]
      index-servers =
        pypi
        django
    
    [pypi]
      username = __token__
      password = # User-scoped or project-scoped token, to set as the default.
    
    [django]
      repository = https://upload.pypi.org/legacy/
      username = __token__
      password = # A project token.
    
  • Доступ к серверу djangoproject.com для загрузки файлов.

  • Доступ к админке на djangoproject.com как «Site maintainer».

  • Доступ к публикации в django-announce.

  • Если это релиз безопасности, доступ к списку рассылки предварительных уведомлений.

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

Предрелизные задачи

Перед началом процесса выпуска необходимо позаботиться о нескольких пунктах. Эта работа начинается примерно за неделю до релиза; большинство из них можно сделать в любое время до самого релиза:

  1. Если это релиз безопасности, разошлите предварительное уведомление за неделю до релиза. Шаблон этого письма и список получателей находятся в закрытой вики django-security GitHub. Сделайте BCC получателям предварительного уведомления. Подпишите письмо ключом, который вы будете использовать для релиза, и включите CVE IDs (запрашивается с Vendor: djangoproject, Product: django) и патчи для каждой исправляемой проблемы. Также, notify django-announce предстоящего релиза безопасности.

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

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

  4. Вычитайте примечания к выпуску, включая просмотр онлайн-версии на предмет ошибок catch any broken links или reST, и убедитесь, что в примечаниях к выпуску указана правильная дата.

  5. Дважды проверьте, чтобы в примечаниях к выпуску были указаны сроки устаревания всех API, отмеченных как устаревшие, и чтобы в них упоминались любые изменения в поддержке версии Python.

  6. Дважды проверьте, что в индексе примечаний к выпуску есть ссылка на примечания к новому выпуску; она будет находиться в docs/releases/index.txt.

  7. Если это функциональный релиз, убедитесь, что переводы из Transifex были интегрированы. Обычно это делает отдельный менеджер перевода, а не выпускающий релиз, но вот порядок действий. При условии, что у вас есть учетная запись на Transifex:

    $ python scripts/manage_translations.py fetch
    

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

  8. Update the django-admin manual page:

    $ cd docs
    $ make man
    $ man _build/man/django-admin.1  # do a quick sanity check
    $ cp _build/man/django-admin.1 man/django-admin.1
    

    и затем зафиксируйте измененную страницу руководства.

  9. Если это альфа-версия новой серии, создайте новую стабильную ветвь из main. Например, при выпуске Django 4.2:

    $ git checkout -b stable/4.2.x origin/main
    $ git push origin -u stable/4.2.x:stable/4.2.x
    

    В то же время обновите переменную django_next_version в docs/conf.py на ветке стабильного релиза, чтобы она указывала на новую версию разработки. Например, при создании stable/4.2.x установите django_next_version на '5.0' в новой ветке.

  10. Если это «нулевой» релиз новой серии, создайте новую ветку от текущей стабильной ветки в репозитории django-docs-translations. Например, при выпуске Django 4.2:

    $ git checkout -b stable/4.2.x origin/stable/4.1.x
    $ git push origin stable/4.2.x:stable/4.2.x
    

Подготовка к выпуску

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

Фактическое развертывание релиза

Итак, наступает самое интересное, когда мы действительно выпускаем релиз!

  1. Проверьте, что Jenkins зеленый для версии (версий), которую вы выпускаете. Возможно, вам не следует выпускать релиз, пока он не станет зеленым.

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

    $ git checkout stable/4.1.x
    $ git pull
    
  3. Если это релиз безопасности, слейте соответствующие патчи из django-security. Перезалейте эти патчи по мере необходимости, чтобы каждый из них стал обычным коммитом в ветке релиза, а не коммитом слияния. Для этого объедините их с флагом --ff-only; например:

    $ git checkout stable/4.1.x
    $ git merge --ff-only security/4.1.x
    

    (При этом предполагается, что security/4.1.x - это ветка в репозитории django-security, содержащая необходимые исправления безопасности для следующего выпуска серии 4.1).

    Если git отказывается сливаться с --ff-only, переключитесь на ветку security-patch и перебазируйте ее на ветку, с которой вы собираетесь слиться (git checkout security/4.1.x; git rebase stable/4.1.x), а затем переключитесь обратно и выполните слияние. Убедитесь, что сообщение о фиксации каждого исправления безопасности объясняет, что фиксация является исправлением безопасности и что за ней последует объявление (example security commit).

  4. Если речь идет о функциональном релизе, удалите заголовок UNDER DEVELOPMENT в верхней части примечаний к релизу и добавьте дату релиза в следующей строке. Для выпуска патча удалите префикс Expected и обновите дату выпуска, если это необходимо. Выполните это изменение во всех ветках, где находятся примечания к выпуску конкретной версии.

  5. Обновите номер версии в django/__init__.py для данного релиза. Подробности о VERSION см. в разделе примечания по установке кортежа VERSION ниже.

  6. Если это предрелизный пакет, обновите классификатор «Статус разработки» в setup.cfg, чтобы отразить это. В противном случае убедитесь, что классификатор установлен в Development Status :: 5 - Production/Stable.

  7. Пометьте релиз с помощью метки git tag. Например:

    $ git tag --sign --message="Tag 4.1.1" 4.1.1
    

    Вы можете проверить свою работу, выполнив git tag --verify <tag>.

  8. Выдвигайте свои работы, включая тег: git push --tags.

  9. Убедитесь, что у вас абсолютно чистое дерево, выполнив git clean -dfx.

  10. Запустите make -f extras/Makefile для генерации пакетов выпуска. Это создаст пакеты релиза в каталоге dist/.

  11. Сгенерировать хэши пакетов релиза:

    $ cd dist
    $ md5sum *
    $ sha1sum *
    $ sha256sum *
    
  12. Создайте файл «checksums», Django-<<VERSION>>.checksum.txt содержащий хэши и информацию о релизе. Начните с этого шаблона и вставьте правильную версию, дату, идентификатор ключа GPG (из gpg --list-keys --keyid-format LONG), имя пользователя GitHub менеджера релиза, URL релиза и контрольные суммы:

    This file contains MD5, SHA1, and SHA256 checksums for the source-code
    tarball and wheel files of Django <<VERSION>>, released <<DATE>>.
    
    To use this file, you will need a working install of PGP or other
    compatible public-key encryption software. You will also need to have
    the Django release manager's public key in your keyring. This key has
    the ID ``XXXXXXXXXXXXXXXX`` and can be imported from the MIT
    keyserver, for example, if using the open-source GNU Privacy Guard
    implementation of PGP:
    
        gpg --keyserver pgp.mit.edu --recv-key XXXXXXXXXXXXXXXX
    
    or via the GitHub API:
    
        curl https://github.com/<<RELEASE MANAGER GITHUB USERNAME>>.gpg | gpg --import -
    
    Once the key is imported, verify this file:
    
        gpg --verify <<THIS FILENAME>>
    
    Once you have verified this file, you can use normal MD5, SHA1, or SHA256
    checksumming applications to generate the checksums of the Django
    package and compare them to the checksums listed below.
    
    Release packages
    ================
    
    https://www.djangoproject.com/m/releases/<<MAJOR VERSION>>/<<RELEASE TAR.GZ FILENAME>>
    https://www.djangoproject.com/m/releases/<<MAJOR VERSION>>/<<RELEASE WHL FILENAME>>
    
    MD5 checksums
    =============
    
    <<MD5SUM>>  <<RELEASE TAR.GZ FILENAME>>
    <<MD5SUM>>  <<RELEASE WHL FILENAME>>
    
    SHA1 checksums
    ==============
    
    <<SHA1SUM>>  <<RELEASE TAR.GZ FILENAME>>
    <<SHA1SUM>>  <<RELEASE WHL FILENAME>>
    
    SHA256 checksums
    ================
    
    <<SHA256SUM>>  <<RELEASE TAR.GZ FILENAME>>
    <<SHA256SUM>>  <<RELEASE WHL FILENAME>>
    
  13. Подпишите файл контрольной суммы (gpg --clearsign --digest-algo SHA256 Django-<version>.checksum.txt). В результате создается подписанный документ Django-<version>.checksum.txt.asc, который затем можно проверить с помощью gpg --verify Django-<version>.checksum.txt.asc.

Если вы выпускаете несколько релизов, повторите эти шаги для каждого релиза.

Сделать релиз(ы) доступным для общественности

Теперь вы готовы выпустить релиз в свет. Для этого:

  1. Загрузите пакет(ы) релиза на сервер djangoproject, заменив A.B. на соответствующий номер версии, например, 4.1 для релиза 4.1.x:

    $ scp Django-* djangoproject.com:/home/www/www/media/releases/A.B
    

    Если это альфа-версия новой серии, вам нужно будет создать каталог A.B.

  2. Загрузите файл(ы) с контрольной суммой:

    $ scp Django-A.B.C.checksum.txt.asc djangoproject.com:/home/www/www/media/pgp/Django-A.B.C.checksum.txt
    
  3. Проверить правильность установки пакетов релиза с помощью pip. Вот один из методов:

    $ RELEASE_VERSION='4.1.1'
    $ MAJOR_VERSION=`echo $RELEASE_VERSION| cut -c 1-3`
    
    $ python -m venv django-pip
    $ . django-pip/bin/activate
    $ python -m pip install https://www.djangoproject.com/m/releases/$MAJOR_VERSION/Django-$RELEASE_VERSION.tar.gz
    $ deactivate
    $ python -m venv django-pip-wheel
    $ . django-pip-wheel/bin/activate
    $ python -m pip install https://www.djangoproject.com/m/releases/$MAJOR_VERSION/Django-$RELEASE_VERSION-py3-none-any.whl
    $ deactivate
    

    Это просто проверяет, что tarballs доступны (т.е. перенаправления работают) и что они устанавливаются правильно, но это позволит отловить глупые ошибки.

  4. Запустите сборку confirm-release на Jenkins для проверки файла(ов) контрольных сумм (например, используйте 4.2rc1 для https://media.djangoproject.com/pgp/Django-4.2rc1.checksum.txt).

  5. Загрузите релизные пакеты на PyPI (для предварительных релизов загрузите только файл wheel):

    $ twine upload -s dist/*
    
  6. Перейдите в раздел Add release page in the admin, введите номер нового релиза точно так, как он указан в названии tarball (Django-<version>.tar.gz). Например, введите «4.1.1» или «4.2rc1» и т.д. Если релиз является частью ветки LTS, отметьте это.

    Если это альфа-версия новой серии, также создайте объект Release для финального выпуска, убедившись, что поле Дата выпуска пустое, тем самым пометив его как невыпущенный. Например, при создании объекта Release для 4.2a1 создайте также объект 4.2 с пустым полем Release date.

  7. Сделайте запись в блоге, анонсирующую релиз, прямой трансляцией.

  8. При выходе новой версии (например, 4.1, 4.2) обновите стабильную версию документации по умолчанию, установив флаг is_default на True для соответствующего объекта DocumentRelease в базе данных docs.djangoproject.com (для всех остальных он автоматически установится на False); сделать это можно с помощью администратора сайта.

    Создать новые объекты DocumentRelease для каждого языка, в котором есть запись для предыдущего выпуска. Обновите файл robots.docs.txt сайта djangoproject.com, скопировав записи из manage_translations.py robots_txt из текущей стабильной ветки в репозиторий django-docs-translations. Например, при выпуске Django 4.2:

    $ git checkout stable/4.2.x
    $ git pull
    $ python manage_translations.py robots_txt
    
  9. Опубликуйте объявление о выпуске в списках рассылки django-announce, django-developers, django-users и на форуме Django. В сообщении должна быть ссылка на запись в блоге анонса.

  10. Если это релиз безопасности, отправьте отдельное письмо на oss-security@lists.openwall.com. Укажите описательную тему, например, «Django» плюс название проблемы из примечаний к релизу (включая CVE ID). В теле сообщения должны содержаться подробности об уязвимости, например, текст сообщения в блоге анонса. Включите ссылку на сообщение в блоге анонса.

  11. Добавьте ссылку на запись в блоге в тему IRC-канала #django: /msg chanserv TOPIC #django new topic goes here.

После освобождения

Вы почти закончили! Все, что теперь осталось сделать, это:

  1. Снова обновите кортеж VERSION в django/__init__.py, увеличив его до следующего ожидаемого релиза. Например, после выпуска версии 4.1.1 обновить VERSION до VERSION = (4, 1, 2, 'alpha', 0).
  2. Добавьте релиз в Trac’s versions list, если необходимо (и сделайте его по умолчанию, изменив настройку default_version в trac.ini на code.djangoproject.com, если это финальный релиз). Новая версия X.Y должна быть добавлена после выхода альфа-версии, а версия по умолчанию должна быть обновлена после выхода «dot zero».
  3. Если это финальный релиз, обновите текущую стабильную ветку и удалите предрелизную ветку в Django release process на Trac.
  4. Если это был выпуск безопасности, обновите Архив вопросов безопасности с подробным описанием устраненных проблем.

Новые задачи стабильной ветки

В период после создания новой стабильной ветки (часто после альфа-релиза) необходимо выполнить несколько задач. Некоторые из этих задач не обязательно должны выполняться релизером.

  1. Создайте новый объект DocumentRelease в базе данных docs.djangoproject.com для документации новой версии и обновите JSON-фиксатор docs/fixtures/doc_releases.json, чтобы люди без доступа к производственной БД могли запустить обновленную копию сайта документации.
  2. Создайте корешок примечания к релизу для новой версии функции. Используйте заглушку из предыдущей версии релиза функции или скопируйте содержимое из предыдущей версии функции и удалите большую часть содержимого, оставив только заголовки.
  3. Увеличить количество итераций PBKDF2 по умолчанию в django.contrib.auth.hashers.PBKDF2PasswordHasher примерно на 20% (выберите круглое число). Запустите тесты и обновите 3 неудачных хэшер-теста, добавив новые значения. Обязательно укажите это в примечаниях к выпуску (см. пример в примечаниях к выпуску 4.1).
  4. Удалите функции, которые достигли конца своего цикла обесценивания. Каждое удаление должно быть выполнено в отдельном коммите для ясности. В сообщении о фиксации добавьте «refs #XXXX» к исходному тикету, в котором началось обесценивание, если это возможно.
  5. Убрать аннотации .. versionadded::, .. versionadded:: и .. deprecated:: в документации двухлетней давности. Например, в Django 4.2 будут удалены примечания для 4.0.
  6. Добавьте новую ветвь в Read the Docs. Поскольку автоматически сгенерированные имена версий («stable-A.B.x») отличаются от имен версий, используемых в Read the Docs («A.B.x»), create a ticket запрашивает новую версию.
  7. Request the new classifier on PyPI. Например, Framework :: Django :: 3.1.
  8. Обновите текущую ветку, находящуюся в активной разработке, и добавьте предрелизную ветку в Django release process на Trac.

Примечания по установке кортежа VERSION

Отчетность о версии в Django контролируется кортежем VERSION в django/__init__.py. Это кортеж из пяти элементов, элементами которого являются:

  1. Основная версия.
  2. Незначительная версия.
  3. Микро версия.
  4. Статус – может быть одним из «alpha», «beta», «rc» или «final».
  5. Номер серии, для пакетов альфа/бета/RC, которые запускаются последовательно (позволяя, например, «beta 1», «beta 2» и т.д.).

Для финального релиза статус всегда «final», а номер серии всегда 0. Номер серии 0 со статусом «альфа» будет представлен как «пре-альфа».

Некоторые примеры:

  • (4, 1, 1, "final", 0) → «4.1.1»
  • (4, 2, 0, "alpha", 0) → «4.2 pre-alpha»
  • (4, 2, 0, "beta", 1) → «4.2 beta 1»
Вернуться на верх