From 582141196218c452e74a7f0192b3fdf9ca0a2b62 Mon Sep 17 00:00:00 2001 From: Vai Patel <6489594+vaipatel@users.noreply.github.com> Date: Sun, 19 Jul 2026 01:54:04 -0400 Subject: [PATCH] Modernize packaging and PyPI release workflow Add a PEP 517 build configuration and replace the legacy setup.py and password-based publishing process with PyPI Trusted Publishing. Update GitHub Actions to current versions and add CI jobs that build and validate distributions, build documentation with warnings treated as errors, and test the minimum supported dependency versions. Raise the dependency floors to NumPy 1.26 and SciPy 1.12, modernize the test and documentation extras, derive the documentation version from the package version, and fix the README markup rejected by `twine check`. --- .github/workflows/build.yml | 50 +++++++++++++++++++++++++++++++-- .github/workflows/publish.yml | 52 +++++++++++++++++++++-------------- CHANGELOG.rst | 3 ++ README.rst | 4 +-- README_for_docs.rst | 4 +-- docs/source/conf.py | 6 ++-- pyproject.toml | 3 ++ setup.py | 11 ++++---- tox.ini | 11 +++++++- 9 files changed, 107 insertions(+), 37 deletions(-) create mode 100644 pyproject.toml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 52b229c..81bed72 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,9 +15,9 @@ jobs: os: [ubuntu-latest, windows-latest, macos-latest] python-version: ['3.12', '3.13', '3.14'] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - name: Display versions @@ -31,3 +31,49 @@ jobs: - name: Run tests with coverage if: ${{ matrix.os == 'ubuntu-latest' && matrix.python-version == '3.14' }} run: pytest --cov=morphops --cov-report=term-missing --pyargs morphops + + minimum-dependencies: + name: ubuntu-latest/py3.12/minimum-dependencies + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 + with: + python-version: '3.12' + - name: Install minimum dependencies and package + run: | + pip install numpy==1.26.4 scipy==1.12.0 pytest + pip install --no-deps -e . + pip check + - name: Run tests + run: pytest --pyargs morphops + + package: + name: Build and validate package + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 + with: + python-version: '3.14' + - name: Build and validate distributions + run: | + pip install build twine + python -m build + twine check dist/* + + docs: + name: Build documentation + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 + with: + python-version: '3.14' + - name: Install package and documentation dependencies + run: pip install -e .'[docs]' + - name: Build documentation + run: sphinx-build -W --keep-going -b html docs/source docs/build/html diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 446df9e..cba9e62 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,7 +1,4 @@ -# This workflow will upload a Python Package using Twine when a release is created -# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries - -name: Upload package to PyPI +name: Publish package to PyPI on: release: @@ -9,22 +6,35 @@ on: - published jobs: - publish-to-pip: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: actions/setup-python@v6 + with: + python-version: '3.x' + - name: Install build tools + run: python -m pip install build + - name: Build distributions + run: python -m build + - uses: actions/upload-artifact@v5 + with: + name: python-package-distributions + path: dist/ + + publish-to-pypi: + needs: build runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/morphops + permissions: + id-token: write steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ runner.python-version }} - uses: actions/setup-python@v2 - with: - python-version: '3.x' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install setuptools wheel twine - - name: Build and publish to PyPI - env: - TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} - TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} - run: | - python setup.py sdist bdist_wheel - twine upload dist/* \ No newline at end of file + - uses: actions/download-artifact@v6 + with: + name: python-package-distributions + path: dist/ + - uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f29c0b3..eaf39fe 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -18,6 +18,9 @@ Changed ------- - Dropped support for Python versions older than 3.12 and updated CI to test Python 3.12 through 3.14. +- Modernized package builds and PyPI publishing, including Trusted Publishing + and CI validation for distributions and documentation. +- Updated the minimum supported dependencies to NumPy 1.26 and SciPy 1.12. Fixed ----- diff --git a/README.rst b/README.rst index da606c5..5cdcf72 100644 --- a/README.rst +++ b/README.rst @@ -118,8 +118,8 @@ they can now be submitted to various commonly used statistical procedures like Principal Components Analysis and various kinds of regression for further analysis. -Contributors ✨ -=============== +Contributors +============ See the project's `contributor acknowledgements `_. The list is maintained with the `All Contributors bot `_. diff --git a/README_for_docs.rst b/README_for_docs.rst index a5682fd..ca4d07d 100644 --- a/README_for_docs.rst +++ b/README_for_docs.rst @@ -126,8 +126,8 @@ they can now be submitted to various commonly used statistical procedures like Principal Components Analysis and various kinds of regression for further analysis. -Contributors ✨ -=============== +Contributors +============ See the project's `contributor acknowledgements `_. The list is maintained with the `All Contributors bot `_. diff --git a/docs/source/conf.py b/docs/source/conf.py index b03d512..0611d3f 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -30,7 +30,7 @@ author = 'Vaibhav Patel' # The short X.Y version -version = '0.1' +version = '.'.join(full_version.split('.')[:2]) # The full version, including alpha/beta/rc tags release = full_version @@ -72,7 +72,7 @@ # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = 'en' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. @@ -210,5 +210,5 @@ # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { 'python': ('https://docs.python.org/3', None), - 'numpy': ('https://docs.scipy.org/doc/numpy/', None) + 'numpy': ('https://numpy.org/doc/stable/', None) } diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..07e10f1 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools >= 77.0.3"] +build-backend = "setuptools.build_meta" diff --git a/setup.py b/setup.py index 99897de..c06b172 100644 --- a/setup.py +++ b/setup.py @@ -2,16 +2,16 @@ from setuptools import setup, find_packages -with open('README.rst') as readme_file: +with open('README.rst', encoding='utf-8') as readme_file: readme = readme_file.read() version = {} -with open("morphops/_version.py") as version_file: +with open("morphops/_version.py", encoding='utf-8') as version_file: exec(version_file.read(), version) extra_feature_requirements = { - "tests": ["coverage >= 5.0", "pytest >= 5.4", "pytest-cov >= 2.8.1", "tox"], - "docs": ["sphinx < 2", "sphinx-rtd-theme"], + "tests": ["pytest >= 8", "pytest-cov >= 5", "tox >= 4"], + "docs": ["sphinx >= 8", "sphinx-rtd-theme >= 3"], } extra_feature_requirements["dev"] = list( chain(*list(extra_feature_requirements.values())) @@ -33,11 +33,10 @@ 'Programming Language :: Python :: 3.12', 'Programming Language :: Python :: 3.13', 'Programming Language :: Python :: 3.14', - 'License :: OSI Approved :: MIT License', 'Topic :: Scientific/Engineering' ], python_requires='>=3.12', extras_require=extra_feature_requirements, - install_requires=['numpy >= 1.13.3', 'scipy >= 1.3.3'], + install_requires=['numpy >= 1.26', 'scipy >= 1.12'], include_package_data=True ) diff --git a/tox.ini b/tox.ini index fb2afb5..436a620 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py312,py313,py314-coverage +envlist = py312-min,py312,py313,py314-coverage [testenv] deps = @@ -7,6 +7,15 @@ deps = commands = pytest -q -s --pyargs morphops +[testenv:py312-min] +basepython = python3.12 +deps = + numpy == 1.26.4 + scipy == 1.12.0 + pytest +commands = + pytest -q -s --pyargs morphops + [testenv:py314-coverage] basepython = python3.14 deps =