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 NOTES.md.

We plan to increase the first digit when dropping a REST API version. We have not needed to do this yet.

Checklist

  1. 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.

  2. Check that there are no files that have not been commited:

    $ git status
    
  3. Run the tests one last time:

    $ tox
    
  4. Check that CHANGELOG.md and NOTES.md are up to snuff. We use towncrier to add to the changelog from the files in changelog.d/.

    Run towncrier build --version 1.5.1. This will update CHANGELOG.md and delete everything in changelog.d/.

    Read the new entry in 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 NOTES.md, feel free to add more detail.

    Use git add -u to ensure the changes to changelog.d/ are included. Make one standalone commit for this step.

  5. Check that HEAD is the commit we want to tag with the new version:

    $ git log --oneline  --decorate HEAD~5..HEAD
    

    This is preferably the commit that adjusted the changelog and notes.

  6. 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.

    $ git tag -m 'Post release bugfixes' v1.5.1
    
  7. Push the tag and changelog commit (given that origin is the correct remote):

    $ git push origin
    

    Note: we bypass pull-requests here.

  8. Create a wheel and source tarball:

    $ python -m build
    

    This will create a wheel in the dist/ directory.

    (You can install build locally for your user with pipx and run pyproject-build instead, it’ll do the same thing.)

  9. 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):

    $ 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:

    $ zipinfo dist/FILENAME.wheel
    
  10. Upload the wheel at PyPI, for instance with twine:

    $ 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 ~/.pypirc.

  11. Turn the tag into a release on Github:

    1. On the “Code” tab, find the column to the right of the list of files and scroll until you find “Releases”. Click on “Releases”.

    2. To the right, find the button “Draft new release”. Click.

    3. Type in the tag in the box that says “Tag version” left of the ‘@’, in order to select the tag.

    4. Copy the tag and date from the changelog to where it says “Release title”.

    5. Copy the changelog into the box below, dedent the headers once.

    6. Finally, click the “Publish release”-button. Done!