mirror of
				https://github.com/django/django.git
				synced 2025-10-31 16:07:30 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			315 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			315 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| =====================
 | |
| How is Django Formed?
 | |
| =====================
 | |
| 
 | |
| This document explains how to release Django. If you're unlucky enough to
 | |
| be driving a release, you should follow these instructions to get the
 | |
| package out.
 | |
| 
 | |
| **Please, keep these instructions up-to-date if you make changes!** The point
 | |
| here is to be descriptive, not proscriptive, so feel free to streamline or
 | |
| otherwise make changes, but **update this document accordingly!**
 | |
| 
 | |
| Overview
 | |
| ========
 | |
| 
 | |
| There are three types of releases that you might need to make
 | |
| 
 | |
| * Security releases, disclosing and fixing a vulnerability. This'll
 | |
|   generally involve two or three simultaneous releases -- e.g.
 | |
|   1.5.X, 1.6.X, and, depending on timing, perhaps a 1.7 alpha/beta/rc.
 | |
| 
 | |
| * Regular version releases, either a final release (e.g. 1.5) or a
 | |
|   bugfix update (e.g. 1.5.1).
 | |
| 
 | |
| * Pre-releases, e.g. 1.6 beta or something.
 | |
| 
 | |
| In general the steps are about the same regardless, but there are a few
 | |
| differences noted. The short version is:
 | |
| 
 | |
| #. If this is a security release, pre-notify the security distribution list
 | |
|    at least one week before the actual release.
 | |
| 
 | |
| #. Proofread (and create if needed) the release notes, looking for
 | |
|    organization, writing errors, deprecation timelines, etc. Draft a blog post
 | |
|    and email announcement.
 | |
| 
 | |
| #. Update version numbers and create the release package(s)!
 | |
| 
 | |
| #. Upload the package(s) to the the ``djangoproject.com`` server and create
 | |
|    some redirects for download/checksum links.
 | |
| 
 | |
| #. Unless this is a pre-release, add the new version(s) to PyPI.
 | |
| 
 | |
| #. Update the home page and download page to link to the new version(s).
 | |
| 
 | |
| #. Post the blog entry and send out the email announcements.
 | |
| 
 | |
| #. Update version numbers post-release.
 | |
| 
 | |
| There are a lot of details, so please read on.
 | |
| 
 | |
| Prerequisites
 | |
| =============
 | |
| 
 | |
| You'll need a few things hooked up to make this work:
 | |
| 
 | |
| * A GPG key. *FIXME: sort out exactly whose keys are acceptable for a
 | |
|   release.*
 | |
| 
 | |
| * Access to Django's record on PyPI.
 | |
| 
 | |
| * Access to the ``djangoproject.com`` server to upload files and trigger a
 | |
|   deploy.
 | |
| 
 | |
| * Access to the admin on ``djangoproject.com``.
 | |
| 
 | |
| * Access to post to ``django-announce``.
 | |
| 
 | |
| * If this is a security release, access to the pre-notification distribution
 | |
|   list.
 | |
| 
 | |
| If this is your first release, you'll need to coordinate with James and Jacob
 | |
| to get all these things ready to go.
 | |
| 
 | |
| Pre-release tasks
 | |
| =================
 | |
| 
 | |
| A few items need to be taken care of before even beginning the release process.
 | |
| This stuff starts about a week before the release; most of it can be done
 | |
| any time leading up to the actual release:
 | |
| 
 | |
| #. If this is a security release, send out pre-notification **one week**
 | |
|    before the release. We maintain a list of who gets these pre-notification
 | |
|    emails at *FIXME WHERE?*. This email should be signed by the key you'll use
 | |
|    for the release, and should include patches for each issue being fixed.
 | |
| 
 | |
| #. As the release approaches, watch Trac to make sure no release blockers
 | |
|    are left for the upcoming release.
 | |
| 
 | |
| #. Check with the other committers to make sure they don't have any
 | |
|    un-committed changes for the release.
 | |
| 
 | |
| #. 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.
 | |
| 
 | |
| #. Double-check that the release notes mention deprecation timelines
 | |
|    for any APIs noted as deprecated, and that they mention any changes
 | |
|    in Python version support.
 | |
| 
 | |
| #. Double-check that the release notes index has a link to the notes
 | |
|    for the new release; this will be in ``docs/releases/index.txt``.
 | |
| 
 | |
| Preparing for release
 | |
| =====================
 | |
| 
 | |
| Next, everything needs to be made ready for actually rolling the
 | |
| release. The following things should be done a few days to a few hours
 | |
| before release:
 | |
| 
 | |
| #. Update the djangoproject home page and download page templates to
 | |
|    reflect the new release. There are two templates to change:
 | |
|    ``flatpages/download.html`` and ``homepage.html``; here's
 | |
|    `one example commit for the 1.4.5 / 1.3.7 releases`__
 | |
| 
 | |
|    __ https://github.com/django/djangoproject.com/commit/772edbc6ac5a2b8e718606b3338f2bcc429fb9b6
 | |
| 
 | |
| #. Write the announcement blog post for the release. You can enter it into
 | |
|    the admin at any time and mark it as inactive. Here are a few examples:
 | |
|    `example security release announcement`__, `example regular release
 | |
|    announcement`__, `example pre-release announcement`__.
 | |
| 
 | |
|    __ https://www.djangoproject.com/weblog/2013/feb/19/security/
 | |
|    __ https://www.djangoproject.com/weblog/2012/mar/23/14/
 | |
|    __ https://www.djangoproject.com/weblog/2012/nov/27/15-beta-1/
 | |
| 
 | |
| #. Create redirects in the admin for the new downloads. For each release,
 | |
|    we create two redirects that look like::
 | |
| 
 | |
|         /download/<version>/tarball/ -> /m/releases/<version>/Django-<version>.tar.gz
 | |
|         /download/<version>/checksum/ -> /m/pgp/Django-<version>.checksum.txt
 | |
| 
 | |
| Actually rolling the release
 | |
| ============================
 | |
| 
 | |
| OK, this is the fun part, where we actually push out a release!
 | |
| 
 | |
| #. Check `Jenkins`__ is green for the version(s) you're putting out. You
 | |
|    probably shouldn't issue a release until it's green.
 | |
| 
 | |
|    __ http://ci.djangoproject.com
 | |
| 
 | |
| #. A release always begins from a release branch, so you should ``git checkout
 | |
|    stable/<release>`` (e.g. checkout ``stable/1.5.x`` to issue a release in the
 | |
|    1.5 series) and then ``git pull`` to make sure you're up-to-date.
 | |
| 
 | |
| 
 | |
| #. If this is a security release, merge the appropriate patches from
 | |
|    ``django-private``. Rebase these patches as necessary to make each one a
 | |
|    simple commit on the release branch rather than a merge commit. To ensure
 | |
|    this, merge them with the ``--ff-only`` flag; for example, ``git checkout
 | |
|    stable/1.5.x; git merge --ff-only security/1.5.x``, if ``security/1.5.x`` is
 | |
|    a branch in the ``django-private`` repo containing the necessary security
 | |
|    patches for the next release in the 1.5 series. If git refuses to merge with
 | |
|    ``--ff-only``, switch to the security-patch branch and rebase it on the
 | |
|    branch you are about to merge it into (``git checkout security/1.5.x; git
 | |
|    rebase stable/1.5.x``) and then switch back and do the merge. Make sure the
 | |
|    commit message for each security fix explains that the commit is a security
 | |
|    fix and that an announcement will follow (`example security commit`__)
 | |
| 
 | |
|    __ https://github.com/django/django/commit/3ef4bbf495cc6c061789132e3d50a8231a89406b
 | |
| 
 | |
| #. Update version numbers for the release. This has to happen in three
 | |
|    places: ``django/__init__.py``, ``docs/conf.py``, and ``setup.py``.
 | |
|    Please see `notes on setting the VERSION tuple`_ below for details
 | |
|    on ``VERSION``. Here's `an example commit updating version numbers`__
 | |
| 
 | |
|    __ https://github.com/django/django/commit/18d920ea4839fb54f9d2a5dcb555b6a5666ee469
 | |
| 
 | |
|    Make sure the ``download_url`` in ``setup.py`` is the actual URL you'll
 | |
|    use for the new release package, not the redirect URL (some tools can't
 | |
|    properly follow redirects).
 | |
| 
 | |
| #. If this is a pre-release package, update the "Development Status" trove
 | |
|    classifier in ``setup.py`` to reflect this. Otherwise, make sure the
 | |
|    classifier is set to ``Development Status :: 5 - Production/Stable``.
 | |
| 
 | |
| #. Tag the release by running ``git tag -s`` *FIXME actual commands*.
 | |
| 
 | |
| #. ``git push`` your work.
 | |
| 
 | |
| #. Make sure you have an absolutely clean tree by running ``git clean -dfx``.
 | |
| 
 | |
| #. Run ``python setup.py sdist`` to generate the release package. This will
 | |
|    create the release package in a ``dist/`` directory.
 | |
| 
 | |
| #. Generate the MD5 and SHA1 hashes of the release package::
 | |
| 
 | |
|         $ md5sum dist/Django-<version>.tar.gz
 | |
|         $ sha1sum dist/Django-<version>.tar.gz
 | |
| 
 | |
| #. Create a "checksums" file containing the hashes and release information.
 | |
|    You can start with `a previous checksums file`__ and replace the
 | |
|    dates, keys, links, and checksums. *FIXME: make a template file.*
 | |
| 
 | |
|    __ https://www.djangoproject.com/m/pgp/Django-1.5b1.checksum.txt
 | |
| 
 | |
| #. Sign the checksum file using the release key (``gpg
 | |
|    --clearsign``), then verify the signature (``gpg --verify``). *FIXME:
 | |
|    full, actual commands here*.
 | |
| 
 | |
| If you're issuing multiple releases, repeat these steps for each release.
 | |
| 
 | |
| Making the release(s) available to the public
 | |
| =============================================
 | |
| 
 | |
| Now you're ready to actually put the release out there. To do this:
 | |
| 
 | |
| #. Upload the release package(s) to the djangoproject server; releases go
 | |
|    in ``/home/www/djangoproject.com/src/media/releases``, under a
 | |
|    directory for the appropriate version number (e.g.
 | |
|    ``/home/www/djangoproject.com/src/media/releases/1.5`` for a ``1.5.X``
 | |
|    release.).
 | |
| 
 | |
| #. Upload the checksum file(s); these go in
 | |
|    ``/home/www/djangoproject.com/src/media/pgp``.
 | |
| 
 | |
| #. Test that the release packages install correctly using ``easy_install``
 | |
|    and ``pip``. Here's one method (which requires `virtualenvwrapper`__)::
 | |
| 
 | |
|         $ mktmpenv
 | |
|         $ easy_install https://www.djangoproject.com/download/<version>/tarball/
 | |
|         $ deactivate
 | |
|         $ mktmpenv
 | |
|         $ pip install https://www.djangoproject.com/download/<version>/tarball/
 | |
|         $ deactivate
 | |
| 
 | |
|    This just tests that the tarballs are available (i.e. redirects are up) and
 | |
|    that they install correctly, but it'll catch silly mistakes. *FIXME:
 | |
|    buildout too?*
 | |
| 
 | |
|    __ https://pypi.python.org/pypi/virtualenvwrapper
 | |
| 
 | |
| #. Ask a few people on IRC to verify the checksums by visiting the checksums
 | |
|    file (e.g. https://www.djangoproject.com/m/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).
 | |
| 
 | |
| #. If this is a security or regular release, register the new package with PyPI
 | |
|    by uploading the ``PGK-INFO`` file generated in the release package.  This
 | |
|    file's *in* the distribution tarball, so you'll need to pull it out. ``tar
 | |
|    xzf dist/Django-<version>.tar.gz Django-<version>/PKG-INFO`` ought to
 | |
|    work. *FIXME: Is there any reason to pull this file out manually rather than
 | |
|    using "python setup.py register"?*
 | |
| 
 | |
| #. Deploy the template changes you made a while back by running `fab deploy`
 | |
|    from the ``djangoproject.com`` repo.
 | |
| 
 | |
| #. Update the ``/download/`` flat page in the djangoproject.com
 | |
|    admin. For alpha/beta/RC releases, we add a temporary third section
 | |
|    to that page listing the preview package; otherwise, just update
 | |
|    the "Get the latest official version" section.
 | |
| 
 | |
| #. Make the blog post announcing the release live.
 | |
| 
 | |
| #. For a new version release (e.g. 1.5, 1.6), update the default stable version
 | |
|    of the docs by flipping the ``is_default`` flag to ``True`` on the
 | |
|    appropriate ``DocumentRelease`` object in the ``docs.djangoproject.com``
 | |
|    database (this will automatically flip it to ``False`` for all
 | |
|    others). *FIXME: I had to do this via fab managepy:shell,docs but we should
 | |
|    probably make it possible to do via the admin.*
 | |
| 
 | |
| #. Post the release announcement to the django-announce,
 | |
|    django-developers and django-users mailing lists. This should
 | |
|    include links to both the announcement blog post and the release
 | |
|    notes. *FIXME: make some templates with example text*.
 | |
| 
 | |
| Post-release
 | |
| ============
 | |
| 
 | |
| You're almost done! All that's left to do now is:
 | |
| 
 | |
| #. Update the ``VERSION`` tuple in ``django/__init__.py`` again,
 | |
|    incrementing to whatever the next expected release will be. For
 | |
|    example, after releasing 1.2.1, update ``VERSION`` to report "1.2.2
 | |
|    pre-alpha". *FIXME: Is this correct? Do we still do this?*
 | |
| 
 | |
| #. For the first alpha release of a new version (when we create the
 | |
|    ``stable/1.?.x`` git branch), you'll want to create a new
 | |
|    ``DocumentRelease`` object in the ``docs.djangoproject.com`` database for
 | |
|    the new version's docs, and update the ``docs/fixtures/doc_releases.json``
 | |
|    JSON fixture. *FIXME: what is the purpose of maintaining this fixture?*
 | |
| 
 | |
| #. Add the release in `Trac's versions list`_.
 | |
| 
 | |
| .. _Trac's versions list: https://code.djangoproject.com/admin/ticket/versions
 | |
| 
 | |
| Notes on setting the VERSION tuple
 | |
| ==================================
 | |
| 
 | |
| Django's version reporting is controlled by the ``VERSION`` tuple in
 | |
| ``django/__init__.py``. This is a five-element tuple, whose elements
 | |
| are:
 | |
| 
 | |
| #. Major version.
 | |
| #. Minor version.
 | |
| #. Micro version.
 | |
| #. Status -- can be one of "alpha", "beta", "rc" or "final".
 | |
| #. Series number, for alpha/beta/RC packages which run in sequence
 | |
|    (allowing, for example, "beta 1", "beta 2", etc.).
 | |
| 
 | |
| For a final release, the status is always "final" and the series
 | |
| number is always 0. A series number of 0 with an "alpha" status will
 | |
| be reported as "pre-alpha".
 | |
| 
 | |
| Some examples:
 | |
| 
 | |
| * ``(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"
 |