How to make a major or minor release - mne-tools/mne-python GitHub Wiki

Important

Before releasing, ensure all milestone issues and PRs are complete, or bump milestones if needed.

Prep: Automated updates using GHA workflows

Prep: Manual steps and commit to main (or PR)

website repo (mne-tools/mne-tools.github.io)

  • Versions more than four years old can be taken offline and archived as zips on the docs-archive release of mne-data, linked from https://mne.tools/dev/old_versions/. To retire X.Y, in the site clone:
    git archive --format=zip --prefix=X.Y/ -o mne-python-docs-X.Y.zip origin/main:X.Y
    gh release upload docs-archive mne-python-docs-X.Y.zip --repo mne-tools/mne-data
    python -m docstacks delete X.Y
    python -m docstacks retitle 0.20 "≤ X.Y ..." --push
    
    Then add the link to doc/old_versions/index.rst.

update changelog

  • Add missing authors. Add anyone who will be missing from the author list (e.g., first-time contributors who did not (co)author any commits but contributed during review/iteration), because the next step builds that list from git shortlog. NOTE: make sure things are clean / not in process before doing this:
    git commit --allow-empty --author="First last <[email protected]>" -m "Empty commit for credit"
  • Build the changelog:
    python tools/dev/finalize_changelog.py X.Y.Z
    It runs towncrier, writes doc/changes/vX.Y.rst (with the version anchor, :newcontrib: entries first in each section, and an Authors list marking first-timers with +), and points the what's new toctree at it. It refuses to build, having written nothing, while any author has no link in doc/changes/names.inc -- that is a .mailmap gap between the commit identity and the credited name, and it prints the line to add.

update some version strings

  • Update the supported version table in SECURITY.md
  • Update the backport-candidate label to say maint/X.Y
  • Change button links doc/install/installers.rst to point to the upcoming new installer files for all platforms.

update codemeta and citation

These files are generated by MNE-Tools, from pyproject.toml plus the extra metadata in .extended_metadata.yaml. They should only be regenerated at release time.

  • Edit .extended_metadata.yaml to update the compound_surnames list (if needed, based on new contributors from the changelog).
  • Then install the mne-tools project and run them, and stage the results:
    python -m mne_tools.generate_codemeta . X.Y.Z
    python -m mne_tools.generate_citation . X.Y.Z
    Both commands take the release version as a required argument, and default to today's date; pass --date-modified YYYY-MM-DD / --release-date YYYY-MM-DD to override.

Fix CircleCI build (if needed)

  • Check the dev docs to make sure it looks OK, and check CircleCI to make sure it was green on the latest scheduled run. If it wasn't or there are problems, fix them before committing.

commit and push

  • ✨ Commit all changes with [circle deploy] and push to main (or open a PR)

Cut the release

GitHub release and tag

  • Use the GitHub feature "Releases" to make a new release. Use vX.Y.Z for all fields (version number, name, description), otherwise they get auto-populated with annoying things. The "target" of the release should be main. This should automatically push to PyPI, which should then automatically trigger a conda-forge update.

Package for Conda

  • The release action opens an issue titled "@conda-forge-admin, please update version" on conda-forge/mne-feedstock as mne-bot once the PyPI upload finishes, and the conda-forge bot answers it with a version-bump PR. Check that the PR appeared, then review it: at a minimum version and sha256 in recipe/meta.yaml are updated automatically, but minimum dependency changes must be edited in by hand (e.g. this PR). If no issue was opened (e.g. the bot token expired), open it manually with that exact title.

Update MNE Installers

  • Update mne-tools/mne-installers. In that repo, use for example git grep "1\.7\.[0-9]" -- ':!*.svg' doc/ to go through and change to X.Y.Z and make a PR.
  • Release MNE-Installers with the new MNE-Python version. This makes the links go live on the websites when they deploy.

Post-release branch updates

Stable / maint/* branches

  • Create and check out a new branch maint/X.Y based on current upstream/main / tag vX.Y.Z
  • Edit pyproject.toml to have version = "X.Y.Z" instead of "dynamic = ["version"].
  • ✨ Commit with [circle deploy] in the commit message and push: this builds the X.Y/ docs and, because X.Y is newer than the current stable, makes them the stable website (see below).
  • Retire CI on the previous stable branch so it stops building nightly: git checkout maint/X.W && git rm .circleci/config.yml && git commit -m "Retire CircleCI on maint/X.W [ci skip]" && git push upstream maint/X.W. A later patch release of that series can restore it with git checkout main -- .circleci/config.yml.
  • Check that https://mne.tools/stable/ is the new version and the switcher dropdown on both stable and an old version (e.g. https://mne.tools/1.11/) lists X.Y (stable).
  • Run the switcher validation (the ignores are archives from before the pydata theme) and make sure it exits 0:
    $ pip install "docstacks @ git+https://github.com/larsoner/docstacks@$(grep -o 'docstacks@[0-9a-f]*' .circleci/config.yml | cut -d@ -f2)"
    $ python -m docstacks validate https://mne.tools/versions.json --check-urls --check-match --ignore 0.20

main updates

  • Restore dev.rst
    cp doc/changes/dev.rst.template doc/changes/dev.rst
    git add doc/changes/dev.rst
  • Add ../changes/dev.rst back into the toctree:: in doc/development/whats_new.rst
  • ✨ Commit and push to main with [circle deploy]

announce the release

  • add a post in the Announcements category on Discourse. After posting, close it (so no replies allowed), then pin it globally.
  • unpin the previous release announcement on Discourse.
  • include update from steering council in release announcement

Close milestone

Do all the deprecations

  • Find all the deprecations that are slated to be removed in the now-current dev version, and open a PR to remove them with something like make -C tools/dev dep, which will git grep deprecation and FutureWarning-related things for you.

stuff we no longer do

package for Debian

  • Check out the repo.
    # make sure your ssh key + ssh config is configured for the remote repo, then:
    git clone ssh://git.debian.org/git/debian-med/python-mne.git
    cd python-mne
    uscan --verbose --force-download
    git import-orig --pristine-tar ../mne-python_XXX.orig.tar.gz
    dch -i  # update changelog + eventually copyright is need files added
  • Remove previous builds if they exist.
    rm -r build
    rm mne/html/bootstrap.min.js
    rm debian/python-mne*
    rm -r debian/python-mne
  • Build the package. git-buildpackage --git-verbose --git-ignore-new -uc -us --git-tag
  • If the build fails: make modifications, commit the patch and try building again: dpkg-source --commit
  • Check conformity to debian build rules.
    lintian -i python-mne*.changes
    cme fix dpkg-copyright  # check formatting of copyright file
  • Commit the release. git push

How to make a minor release

  1. Check out upstream/maint/1.10 or similar
  2. Update version number in pyproject.toml
  3. Manually take any doc/changes/dev/*.rst and put in doc/changes/v1.10.rst under a new 1.10.1 (<date>) heading
  4. Update links in doc/install/installers.rst (knowing the next installer version number)
  5. Update codemeta and citation:
    python -m mne_tools.generate_codemeta . X.Y.Z
    python -m mne_tools.generate_citation . X.Y.Z
  6. Commit, push to maint/1.10 (e.g., 2efba964)
  7. Cut a new release on GitHub making sure to use maint/1.10 as the target, not main!
  8. Update conda-forge recipe (diff)
  9. Update mne-installers (bump, release, wait for release to finish, finalize release)
  10. Update installer links on dev (and maint/1.10 if not done already)
⚠️ **GitHub.com Fallback** ⚠️