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

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

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

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

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

  • Релизы безопасности: раскрытие и устранение уязвимости. Обычно это включает два или три одновременных релиза - например, 1.5.x, 1.6.x и, в зависимости от времени, возможно, альфа/бета/rc 1.7.
  • Регулярные выпуски версий: либо финальный релиз (например, 1.5), либо обновление с исправлением ошибок (например, 1.5.1).
  • Предварительные версии: например, 1.6 alpha, beta или rc.

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

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

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

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

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

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

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

    $ python -m pip install wheel twine
    
  • Доступ к записи Django на PyPI. Создайте файл с вашими учетными данными:

    ~/.pypirc
    [pypi]
    username:YourUsername
    password:YourPassword
    
  • Доступ к серверу 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. Check with the other mergers to make sure they don’t have any uncommitted changes for the release.

  4. Proofread the release notes, including looking at the online version to catch any broken links or reST errors, and make sure the release notes contain the correct date.

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

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

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

    $ python scripts/manage_translations.py fetch
    

    and then commit the changed/added files (both .po and .mo). Sometimes there are validation errors which need to be debugged, so avoid doing this task immediately before a release is needed.

  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. If this is the alpha release of a new series, create a new stable branch from main. For example, when releasing Django 3.1:

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

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

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

    $ git checkout -b stable/2.2.x origin/stable/2.1.x
    $ git push origin stable/2.2.x:stable/2.2.x
    

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

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

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

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

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

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

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

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

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

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

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

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

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

  7. Пометьте релиз, используя git tag. Например:

    $ git tag --sign --message="Tag 1.5.1" 1.5.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. Create a «checksums» file, Django-<<VERSION>>.checksum.txt containing the hashes and release information. Start with this template and insert the correct version, date, GPG key ID (from gpg --list-keys --keyid-format LONG), release manager’s GitHub username, release URL, and checksums:

    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/<<RELEASE TAR.GZ FILENAME>>
    https://www.djangoproject.com/m/releases/<<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. на соответствующий номер версии, например, 1.5 для релиза 1.5.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. Test that the release packages install correctly using pip. Here’s one method:

    $ RELEASE_VERSION='1.7.2'
    $ 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. Ask a few people on IRC to verify the checksums by visiting the checksums file (e.g. https://media.djangoproject.com/pgp/Django-1.5b1.checksum.txt) and following the instructions in it. For bonus points, they can also unpack the downloaded release tarball and verify that its contents appear to be correct (proper version numbers, no stray .pyc or other undesirable files).

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

    $ twine upload -s dist/*
    
  6. Go to the Add release page in the admin, enter the new release number exactly as it appears in the name of the tarball (Django-<version>.tar.gz). So for example enter «1.5.1» or «1.4c2», etc. If the release is part of an LTS branch, mark it so.

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

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

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

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

    $ git checkout stable/2.2.x
    $ git pull
    $ python manage_translations.py robots_txt
    
  9. Опубликуйте анонс релиза в списках рассылки django-announce, django-developers и django-users. Это должно включать ссылку на сообщение в блоге анонса.

  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, увеличивая его до следующего ожидаемого релиза. Например, после выпуска версии 1.5.1 обновите VERSION до VERSION = (1, 5, 2, 'alpha', 0).
  2. При необходимости добавьте релиз в Trac’s versions list (и сделайте его по умолчанию, изменив настройку default_version в trac.ini code.djangoproject.com, если это финальный релиз). Новая версия X.Y должна быть добавлена после выхода альфа-версии, а версия по умолчанию должна быть обновлена после выхода «dot zero».
  3. Если это был выпуск безопасности, обновите Архив вопросов безопасности с подробным описанием устраненных проблем.

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

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

  1. Создайте новый объект DocumentRelease в базе данных docs.djangoproject.com для документации новой версии и обновите JSON-фиксатор docs/fixtures/doc_releases.json, чтобы люди без доступа к производственной БД могли запустить обновленную копию сайта документации.
  2. Создайте корешок примечания к релизу для новой версии функции. Используйте заглушку из предыдущей версии релиза функции или скопируйте содержимое из предыдущей версии функции и удалите большую часть содержимого, оставив только заголовки.
  3. Увеличьте количество итераций PBKDF2 по умолчанию в django.contrib.auth.hashers.PBKDF2PasswordHasher примерно на 20% (выберите круглое число). Запустите тесты и обновите 3 неудачных теста хешера новыми значениями. Убедитесь, что это будет отмечено в примечаниях к выпуску (пример см. в примечаниях к выпуску 1.8).
  4. Удалите функции, которые достигли конца своего цикла обесценивания. Каждое удаление должно быть выполнено в отдельном коммите для ясности. В сообщении о фиксации добавьте «refs #XXXX» к исходному тикету, в котором началось обесценивание, если это возможно.
  5. Удалите аннотации .. versionadded::, .. versionadded:: и .. deprecated:: в документации от двух релизов назад. Например, в Django 1.9 будут удалены аннотации для 1.7.
  6. Add the new branch to Read the Docs. Since the automatically generated version names («stable-A.B.x») differ from the version names used in Read the Docs («A.B.x»), create a ticket requesting the new version.
  7. Request the new classifier on PyPI. Например, Framework:: Django:: 3.1.

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

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

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

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

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

  • (1, 2, 1, 'final', 0) → «1.2.1»
  • (1, 3, 0, 'alpha', 0) → «1.3 pre-alpha»
  • (1, 3, 0, 'beta', 2) → «1.3 beta 2»
Вернуться на верх