Skip to content

How to make a release

Stefan Appelhoff edited this page Nov 16, 2024 · 49 revisions

Versioning of MNE-BIDS

MNE-BIDS loosely follows semver:

  • Versions consist of strings like 0.11.1, where the components refer to major.minor.patch versions.
  • On GitHub releases, the versions are prepended with a v, that is, 0.15.0 becomes v0.15.0. On PyPI and Conda-Forge, this is not the case.
  • While we are in the 0 major version, breaking changes are permitted without incrementing the major version (that is, a minor release is okay).
  • The MNE-BIDS documentation is version-tracked only for major and minor versions. Patch releases get merged into the documentation version of the corresponding major/minor version. For example, for 0.15.1, no new documentation version is created, but the documentation version of 0.15.0 is updated
    • Note that this means that doc version updates from, for example, 0.15.1 will also occur in the doc version for 0.16.0

Deviations from "semver"

  • Before release 0.15.0, for versions where the patch was 0, that component was omitted from the version, that is, 0.11.0 was simplified to 0.11.

Before making a release

NOTE

The instructions below all refer to a major or minor release. For a patch release, see How to make a patch release.

  • Make sure all milestones are achieved (closed) or migrated to the next version
  • Also check the projects page for open issues and either finish or migrate them to the next version
  • Make sure all CI checks pass on main
    • If you are using the "main"/"dev" version for external packages in your CIs (e.g., mne, bids-validator), you will need to adjust this to point to a specific commit or stable version.
    • Else this will lead to problems in the future, when an old release of mne-bids will still use the main version in the CIs, for building the docs, etc.
    • Furthermore, PyPI may reject the dist, if for example GitHub repos at specific commits are pinned as dependencies
    • Files to look at are:
      • .github/workflows/unit_tests.yml
      • circleci/config.yml
      • pyproject.toml
    • You may also want to check that all tests and building the docs pass locally on your machine

Start a new PR, preparing a release

  • Add new lines to the doc/_static/versions.json file to reflect a new release
    1. Copy the first dict in the list and paste it right below
    2. Increment the version value in the first dict in the list dict by a minor step (for name, e.g., 0.15 --> 0.16)
    3. Edit the second dict in the the list (for name: devel --> stable; for version: dev --> stable; and for url: https://mne.tools/mne-bids/dev/ --> https://mne.tools/mne-bids/<version>/, where you adjust <version> appropriately)
    4. Edit the third dict in the list (for name: remove (stable); for version: add the version, e.g., 0.14)
  • Edit whats_new.rst according to the schema that was used for previous releases
    • Make sure you add the correct release date
    • Make sure that the release specific authors section is accurate and up to date
    • Run git shortlog v0.15.0..HEAD --summary --numbered --email (replace the version tag to the most recently released version) to find contributor names for this release
    • If necessary, update the .mailmap file at this point, so that each author/contributor has one identity (name+email), instead of several
    • Manually add authors who have done a lot of work (reviewing, advising, ...) but don't show up in the shortlog because they did not submit PRs
    • Then order the names alphabetically and add to the relevant section of the version-to-be-released's changelog
  • Merge the PR into main using SQUASH and merge ... the release PR should be a single commit

Make the release and push it to PyPI

  • Make an annotated tag for the version: git tag -a -m "v0.15.0" v0.15.0 upstream/main
  • Push the tag to GitHub: git push upstream v0.15.0
  • Use the GitHub feature "Releases" to make a new release on the newly pushed tag, for example, v0.15.0. Use v0.15.0 also for the "Release title" field, and feel free to "auto generate" release notes via GitHub
    • this should push the package to PyPI, see .github/workflows/release.yml

Prepare stable docs

  • Wait until the most recent CI runs have completed (those triggered by pushing the tag!), look here: https://github.com/mne-tools/mne-bids/actions/workflows/unit_tests.yml
  • Download the corresponding doc build artifacts from the build_docs GitHub action step
  • From main, branch off a maint/0.15 branch (or whatever the version-to-be-released is; NOTE: skip the patch version!)
  • Push the maint/0.15 branch to upstream
  • On the gh-pages branch:
    • First, have a look at the git log. You will see many commits of the type: doc updates [skip ci]. These commits are auto-generated to push the most recent (dev) docs to the branch after every commit. As part of the release of a new version, we squash these commits. Simply find the last meaningful commit hash before a sequence of doc updates [skip ci], and then call git rebase -i <hash> with the hash you found, squashing all meaningless commits. Then commit and force push these updates to the gh-pages branch upstream.
    • Add a new folder v0.15 where you put the contents of the doc build artifacts
    • Replace the contents of the stable folder with the same contents
    • This is effectively duplicating the doc/_build/html contents, but that's okay, and we want that (see wiki entry on docs)
    • Push all of this, so that it's upstream in mne-tools's gh-pages branch

Cleaning up

  • Close the v0.15 milestone and project on GitHub ... open new milestone and project for next version, in case you did not do so already
  • Move the newest changelog to whats_new_previous_releases.rst and edit whats_new.rst to reflect a new development cycle (it's "unreleased", and the subheadings won't have items)

How to make a patch release

Please be familiar with the usual release protocol (see above) before proceeding.

  • First, checkout the maint/0.15 (or whatever version was most recently released) branch
  • Then use git cherry-pick <commit> to add commits from main to maint/0.15
  • Make sure that you only add commits that are bug fixes
  • Make sure that the commits you add do not change dependencies or other infrastructure requirements
  • You most likely will need to resolve some merge conflicts, in particular with regards to the changelog
    • make a new section in the changelog (whats_new.rst): Version 0.15.1 (YYYY-MM-DD)
    • list all new changes in that section, and add the following intro sentence:
    • Version 0.15.1 is a patch release, all changes are listed below. For more complete information on the 0.15.0 version, see changelog below.

Once you have added all commits that you want to release to the branch, continue as follows:

  • From the maint/0.15 (for example) branch, make an annotated tag for the version: git tag -a -m "v0.15.1" v0.15.1 upstream/main
  • Push the tag upstream: git push upstream v0.15.1 and make a GitHub release of the version, using the new tag
    • this will build the distribution and push it to PyPI
  • Download the appropriate build artifacts for the docs as for a normal release and push the built docs to the v0.15 and stable folders on the gh-pages branch

Updating the conda package

The conda-forge channel includes a conda package of mne-bids. A dedicated git repository, which is called a feedstock in conda-forge terms, contains the recipe describing all steps required to build and test the package; it can be found at recipe/meta.yaml.

Whenever a new version of mne-bids is published on PyPI, a conda-forge bot will automatically open a Pull Request (PR) to update the following parts of meta.yaml:

  • version number, e.g. {% set version = "0.3" %}

  • SHA256 hash of the source archive, e.g. sha256: 187add419562e3607c161eaf04971863c134febad2e70313260a58238e519ba5

  • build number is reset to zero: number: 0

Before merging, please check whether the dependencies of mne-bids have changed. If that's the case, you have two options, described below.

Updating dependencies via GitHub browser interface

This is the most straightforward option:

  • using your web browser, navigate to the bot's branch of mne-bids-feedstock it wants to merge (you can simply follow the link on top of the respective PR page)
  • navigate to recipe/meta.yaml, and click on the edit button
  • adjust the package dependencies in the requirements: run section
  • commit the changes directly to the bot's branch (all recipe maintainers have write access)
  • wait for CI to successfully finish and merge the PR

Updating dependencies locally

If you prefer not to use the web interface:

  • fork the bot's fork of the mne-bids-feedstock repository (or add it as a remote)
  • checkout the respective branch (it's typically called vXY, where XY is the version number, e.g., v0.3)
  • adjust the package dependencies in the requirements: run section of recipe/meta.yaml
  • commit and push the changes to the bot's branch
  • wait for CI to successfully finish and merge the PR

After the changes have been merged and the package is built, it may take up to 60 minutes to propagate across all conda-forge mirrors.

Other changes to the recipe

Of course, changes to the recipe are not bound to a new upstream release. You may change any part of the recipe at any time.

It is important to always work on a branch of your fork of mne-bids-feedstock. Even if you are a recipe maintainer (which provides you with write access to the mne-bids-feedstock repository), do not create branches on that repository directly (or, even worse, commit to its master branch).

  • increase the build number
  • open a a PR
  • rerender the feedstock by posting @conda-forge-admin, please rerender as a comment to the PR
  • merge the PR once all tests have passed

Again, it may take up to 60 minutes for the new package to appear on all mirrors.

See the conda-forge documentation for additional information.