.. set tw: 72 ========================== How To: Make a new release ========================== This howto uses version number "1.5.1" throughout as an example. Remember to edit all copy-pastes that have "1.5.1" in them to the correct version number! Choosing a version number ------------------------- While we use `SemVer `_, SemVer is open to interpretation so here is ours. Increase the middle digit every time when * there is a change in the database schema that necessitates a migration on the production SQL server. (Django also has migrations that do *not* necessitate this.) * there is a change that automatically rewrites the data in the database (aka a "data migration") * there is a change in the REST API that cannot be ignored by clients (especially *removed* attributes) * there is a wonderful new feature that needs to be highlighted * the deployer needs to do extra steps, like ensuring that a new dependency is installed * there is a bugfix that necessitates some hands-on action from the deployer Increase the final digit when * changing documentation * changing something in CI/CD like updating CI/CD specific dependencies * adding a bugfix that nobody should notice Releases that only change the final digit should *never* be mentioned in :file:`NOTES.md`. We plan to increase the first digit when dropping a REST API version. We have not needed to do this yet. Checklist --------- #. Ensure you're on the correct branch to be released. Either ``master`` or newest stable, which has a name of the form ``stable/1.5.x``. Release from the stable branch only under exceptional circumstances. For instance: there's a critical bugfix for production and there's a lot of new stuff on master that is not ready to go. #. Check that there are no files that have not been commited: .. code:: console $ git status #. Run the tests one last time: .. code:: console $ tox #. Check that :file:`CHANGELOG.md` and :file:`NOTES.md` are up to snuff. We use :command:`towncrier` to add to the changelog from the files in :file:`changelog.d/`. Run :code:`towncrier build --version 1.5.1`. This will update :file:`CHANGELOG.md` and delete everything in :file:`changelog.d/`. Read the new entry in :file:`CHANGELOG.md` and adjust it as necessary for better language. Reorder as per the order the commits/pull-requests were commited, newest on top. That makes it easier to compare with the ``git log`` for maximum detail. Copy steps that a deployer needs to do to :file:`NOTES.md`, feel free to add more detail. Use ``git add -u`` to ensure the changes to :file:`changelog.d/` are included. Make one standalone commit for this step. #. Check that HEAD is the commit we want to tag with the new version: .. code:: console $ git log --oneline --decorate HEAD~5..HEAD This is preferably the commit that adjusted the changelog and notes. #. Tag the correct commit with an annotated tag. The format of the tag itself is ``vX.Y.Z`` where X, Y and Z are integers. Don't forget the ``v``. The annotation should be a very brief summary of the most important changes. The annotation need not be unique, there just must be *something* to make the tag annotated. .. code:: console $ git tag -m 'Post release bugfixes' v1.5.1 #. Push the tag and changelog commit (given that ``origin`` is the correct remote): .. code:: console $ git push origin Note: we bypass pull-requests here. #. Create a wheel and source tarball: .. code:: console $ python -m build This will create a wheel in the :file:`dist/` directory. (You can install ``build`` locally for your user with :command:`pipx` and run :command:`pyproject-build` instead, it'll do the same thing.) #. Do a quick manual check of the contents of the wheel: Check that the correct version is in the filename (if not, you might have forgotten to tag, or the git index is dirty): .. code:: console $ ls dist/ Then check the contents with any tool that can analyze a zip-file, for instance ``zipinfo``. Check that no unwanted files are included, like editor swap files, ``.pyc`` files, or ``__pycache__`` directories: .. code:: console $ zipinfo dist/FILENAME.wheel #. Upload the wheel at `PyPI `_, for instance with `twine `_: .. code:: console $ twine upload dist/*.whl Use your own user if you've been given access or ask for a token for the team-user, see also :file:`~/.pypirc`. #. Turn the tag into a release on Github: #. On the "Code" tab, find the column to the right of the list of files and scroll until you find "Releases". Click on "Releases". #. To the right, find the button "Draft new release". Click. #. Type in the tag in the box that says "Tag version" left of the '@', in order to select the tag. #. Copy the tag and date from the changelog to where it says "Release title". #. Copy the changelog into the box below, dedent the headers once. #. Finally, click the "Publish release"-button. Done!