How to cut a Toga release

The release infrastructure for Toga is semi-automated, using GitHub Actions to formally publish releases.

This guide assumes that you have an upstream remote configured on your local clone of the Toga repository, pointing at the official repository. If all you have is a checkout of a personal fork of the Toga repository, you can configure that checkout by running:

$ git remote add upstream

The procedure for cutting a new release is as follows:

  1. Check the contents of the upstream repository’s main branch:

    $ git fetch upstream
    $ git checkout --detach upstream/main

    Check that the HEAD of release now matches upstream/main.

  2. Ensure that the release notes are up to date. Run:

    $ tox -e towncrier -- --draft

    to review the release notes that will be included, and then:

    $ tox -e towncrier

    to generate the updated release notes.

  3. Build the documentation to ensure that the new release notes don’t include any spelling errors or markup problems:

    $ tox -e docs-lint,docs
  4. Tag the release, and push the branch and tag upstream:

    $ git tag v1.2.3
    $ git push upstream HEAD:main
    $ git push upstream v1.2.3
  5. Pushing the tag will start a workflow to create a draft release on GitHub. You can follow the progress of the workflow on GitHub; once the workflow completes, there should be a new draft release, and entries on the TestPyPI server for toga-core, toga-cocoa, etc.

    Confirm that this action successfully completes. If it fails, there’s a couple of possible causes:

    1. The final upload to TestPyPI failed. TestPyPI doesn’t have the same service monitoring as PyPI-proper, so it sometimes has problems. However, it’s not critical to the release process.

    2. Something else fails in the build process. If the problem can be fixed without a code change to the Toga repository (e.g., a transient problem with build machines not being available), you can re-run the action that failed through the GitHub Actions GUI. If the fix requires a code change, delete the old tag, make the code change, and re-tag the release.

  6. Create a clean virtual environment, install the new release from Test PyPI, and perform any pre-release testing that may be appropriate:

    $ python3 -m venv testvenv
    $ . ./testvenv/bin/activate
    (testvenv) $ pip install --extra-index-url toga==1.2.3
    (testvenv) $ toga-demo
    (testvenv) $ #... any other manual checks you want to perform ...
  7. Log into ReadTheDocs, visit the Versions tab, and activate the new version. Ensure that the build completes; if there’s a problem, you may need to correct the build configuration, roll back and re-tag the release.

  8. Edit the GitHub release to add release notes. You can use the text generated by Towncrier, but you’ll need to update the format to Markdown, rather than ReST. If necessary, check the pre-release checkbox.

  9. Double check everything, then click Publish. This will trigger a publication workflow on GitHub.

  10. Wait for the packages to appear on PyPI (toga-core, toga-cocoa, etc.).

Congratulations, you’ve just published a release!

Once the release has successfully appeared on PyPI or TestPyPI, it cannot be changed. If you spot a problem after that point, you’ll need to restart with a new version number.