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 =