From e1bd291969bb44fe042bada7fe5f1b3ba397b2b2 Mon Sep 17 00:00:00 2001 From: Leonardo Uieda Date: Wed, 2 Nov 2022 17:58:15 +0000 Subject: [PATCH] Set lower bounds for supported dependency versions (#356) Follow NEP29 and set lower bounds for the dependencies (all minor versions from the last 2 years). The only exception is xrft, which is new and likely requires v1.0 to work with Harmonica. Setup CI to run on lowest Python with lowest dependencies, highest Python with highest dependencies, and highest Python with optional dependencies. Use Dependente to extract the version information from setup.cfg instead of the custom export tool we had. --- .github/workflows/docs.yml | 16 ++++----- .github/workflows/test.yml | 41 ++++++++++++++--------- doc/compatibility.rst | 64 ++++++++++++++++++++++++++++++++++++ doc/index.rst | 3 +- doc/install.rst | 6 ++++ environment.yml | 20 +++++------ setup.cfg | 20 +++++------ tools/export_requirements.py | 19 ----------- 8 files changed, 125 insertions(+), 64 deletions(-) create mode 100644 doc/compatibility.rst delete mode 100644 tools/export_requirements.py diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index dd6e0aa54..7aac0b3f6 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -71,25 +71,25 @@ jobs: # Needed for caching use-only-tar-bz2: true - - name: Collect requirements - run-time - run: python tools/export_requirements.py > requirements-full.txt - - - name: Collect requirements - other + - name: Collect requirements run: | + echo "Install Dependente to capture dependencies:" + mamba install dependente==0.1.0 -c conda-forge + echo "" + echo "Capturing run-time dependencies:" + dependente --source install > requirements-full.txt echo "Capturing dependencies from:" for requirement in $REQUIREMENTS do echo " $requirement" cat $requirement >> requirements-full.txt done - - - name: List requirements - run: | + echo "" echo "Collected dependencies:" cat requirements-full.txt - name: Setup caching for conda packages - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ~/conda_pkgs_dir key: conda-${{ runner.os }}-${{ env.PYTHON }}-${{ hashFiles('requirements-full.txt') }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8b2b3a209..935b44f9b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -38,13 +38,19 @@ jobs: - ubuntu - macos - windows - python: - - "3.7" - - "3.9" dependencies: + - oldest - latest + - optional + include: + - dependencies: oldest + python: "3.7" + - dependencies: latest + python: "3.9" + - dependencies: optional + python: "3.9" env: - REQUIREMENTS: env/requirements-tests.txt + REQUIREMENTS: env/requirements-build.txt env/requirements-tests.txt # Used to tag codecov submissions OS: ${{ matrix.os }} PYTHON: ${{ matrix.python }} @@ -81,39 +87,42 @@ jobs: with: python-version: ${{ matrix.python }} - - name: Collect requirements - run-time - run: python tools/export_requirements.py > requirements-full.txt - - - name: Collect requirements - other + - name: Collect requirements run: | + echo "Install Dependente to capture dependencies:" + python -m pip install dependente==0.1.0 + echo "" + echo "Capturing run-time dependencies:" + if [[ "${{ matrix.dependencies }}" == "oldest" ]]; then + dependente --source install --oldest > requirements-full.txt + elif [[ "${{ matrix.dependencies }}" == "optional" ]]; then + dependente --source install,extras > requirements-full.txt + else + dependente --source install > requirements-full.txt + fi echo "Capturing dependencies from:" for requirement in $REQUIREMENTS do echo " $requirement" cat $requirement >> requirements-full.txt done - - - name: List requirements - run: | + echo "" echo "Collected dependencies:" cat requirements-full.txt - name: Get the pip cache folder id: pip-cache run: | - echo "::set-output name=dir::$(pip cache dir)" + echo "dir="$(pip cache dir) >> $GITHUB_OUTPUT - name: Setup caching for pip packages - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('requirements-full.txt') }} - name: Install requirements run: | - # Install the build requirements before anything else so pip can use - # wheels for other packages. - python -m pip install --requirement env/requirements-build.txt python -m pip install --requirement requirements-full.txt - name: Build source and wheel distributions diff --git a/doc/compatibility.rst b/doc/compatibility.rst new file mode 100644 index 000000000..5caf1ee5c --- /dev/null +++ b/doc/compatibility.rst @@ -0,0 +1,64 @@ +.. _compatibility: + +Version compatibility +===================== + +Harmonica version compatibility +------------------------------- + +Harmonica uses `semantic versioning `__ (i.e., +``MAJOR.MINOR.BUGFIX`` format). + +* Major releases mean that backwards incompatible changes were made. + Upgrading will require users to change their code. +* Minor releases add new features/data without changing existing functionality. + Users can upgrade minor versions without changing their code. +* Bug fix releases fix errors in a previous release without adding new + functionality. Users can upgrade minor versions without changing their code. + +We will add ``FutureWarning`` messages about deprecations ahead of making any +breaking changes to give users a chance to upgrade. + +.. warning:: + + The above does not apply to versions < ``1.0.0``. All ``0.*`` versions may + deprecate, remove, or change functionality between releases. Proper + warnings will be raised and any breaking changes will be marked as such in + the :ref:`changes`. + +.. _dependency-versions: + +Supported dependency versions +----------------------------- + +Harmonica follows the recommendations in +`NEP29 `__ for setting +the minimum required version of our dependencies. +In short, we support **all minor releases of our dependencies from the previous +24 months** before a Harmonica release with a minimum of 2 minor releases. + +We follow this guidance conservatively and won't require newer versions if the +older ones are still working without causing problems. +Whenever support for a version is dropped, we will include a note in the +:ref:`changes`. + +.. note:: + + This was introduced in Harmonica v0.6.0. + + +.. _python-versions: + +Supported Python versions +------------------------- + +If you require support for older Python versions, please pin Harmonica to the +following releases to ensure compatibility: + +.. list-table:: + :widths: 40 60 + + * - **Python version** + - **Last compatible release** + * - 3.6 + - 0.5.0 diff --git a/doc/index.rst b/doc/index.rst index 8f7521470..75f785de8 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -184,8 +184,9 @@ That's how we all improve and we are happy to help others learn. api/index.rst citing.rst - changes.rst references.rst + changes.rst + compatibility.rst versions.rst .. toctree:: diff --git a/doc/install.rst b/doc/install.rst index 2f6cd4c1c..3b7410291 100644 --- a/doc/install.rst +++ b/doc/install.rst @@ -7,6 +7,7 @@ Which Python? ------------- You'll need **Python 3.7 or greater**. +See :ref:`python-versions` if you require support for older versions. We recommend using the `Anaconda Python distribution `__ @@ -23,6 +24,11 @@ The required dependencies should be installed automatically when you install Harmonica using ``conda`` or ``pip``. Optional dependencies have to be installed manually. +.. note:: + + See :ref:`dependency-versions` for the our policy of oldest supported + versions of each dependency. + Required: * `numpy `__ diff --git a/environment.yml b/environment.yml index cae320ea2..21558fd82 100644 --- a/environment.yml +++ b/environment.yml @@ -11,17 +11,17 @@ dependencies: - wheel - twine # Run-time - - numpy - - pandas - - numba - - scipy - - scikit-learn - - pooch>=0.7.0 - - verde>=1.5.0 - - xarray - - xrft + - numpy>=1.19 + - pandas>=1.1 + - numba>=0.52 + - scipy>=1.5 + - scikit-learn>=0.24 + - pooch>=1.2 + - verde>=1.7.0 + - xarray>=0.16 + - xrft>=1.0 # Optional requirements - - pyvista + - pyvista>=0.27 - vtk>=9 # Testing requirements - pytest diff --git a/setup.cfg b/setup.cfg index 0ecfe2454..ef0401f34 100644 --- a/setup.cfg +++ b/setup.cfg @@ -39,19 +39,19 @@ include_package_data = True packages = find: python_requires = >=3.7 install_requires = - numpy - pandas - scipy - scikit-learn - numba - pooch>=0.7.0 - xarray - verde>=1.5.0 - xrft + numpy>=1.19 + pandas>=1.1 + scipy>=1.5 + scikit-learn>=0.24 + numba>=0.52 + pooch>=1.2 + xarray>=0.16 + verde>=1.7 + xrft>=1.0 [options.extras_require] visualizations = - pyvista + pyvista>=0.27 vtk>=9 [options.package_data] diff --git a/tools/export_requirements.py b/tools/export_requirements.py deleted file mode 100644 index bf3d9028d..000000000 --- a/tools/export_requirements.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2018 The Harmonica Developers. -# Distributed under the terms of the BSD 3-Clause License. -# SPDX-License-Identifier: BSD-3-Clause -# -# This code is part of the Fatiando a Terra project (https://www.fatiando.org) -# -""" -Export the run-time requirements from setup.cfg to a requirement.txt format. -Modified from https://github.com/Unidata/MetPy -""" -import configparser - -# Read the setup.cfg -config = configparser.ConfigParser() -config.read("setup.cfg") - -print("# Run-time dependencies") -for package in config["options"]["install_requires"].strip().split("\n"): - print(package.strip())