diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..0f96f8d --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,9 @@ +# Set update schedule for GitHub Actions + +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + # Check for updates to GitHub Actions every week + interval: "weekly" diff --git a/.github/workflows/build_and_deploy.yml b/.github/workflows/build_and_deploy.yml new file mode 100644 index 0000000..dfbbfdc --- /dev/null +++ b/.github/workflows/build_and_deploy.yml @@ -0,0 +1,58 @@ +name: Build + +on: [push, pull_request] + +jobs: + build_wheels: + name: Build wheels on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + + steps: + - uses: actions/checkout@v4 + + - name: Build wheels + uses: pypa/cibuildwheel@v2.16.5 + env: + CIBW_SKIP: "pp* cp36-* cp37-* *win_arm64 *_i686 *musllinux*" + + - uses: actions/upload-artifact@v4 + with: + name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} + path: ./wheelhouse/*.whl + + build_sdist: + name: Build source distribution + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Build sdist + run: pipx run build --sdist + + - uses: actions/upload-artifact@v4 + with: + name: cibw-sdist + path: dist/*.tar.gz + + upload_pypi: + name: Upload release to PyPI + needs: [build_wheels, build_sdist] + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/ripser + permissions: + id-token: write + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + steps: + - uses: actions/download-artifact@v4 + with: + # unpacks all CIBW artifacts into dist/ + pattern: cibw-* + path: dist + merge-multiple: true + + - uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml deleted file mode 100644 index d58a93f..0000000 --- a/.github/workflows/python-publish.yml +++ /dev/null @@ -1,73 +0,0 @@ -# This workflows 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 Python Package - -on: - release: - types: [created] - workflow_dispatch: - -jobs: - deploy-unix: - strategy: - fail-fast: false - matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] - - runs-on: "ubuntu-latest" - steps: - - uses: actions/checkout@v2 - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - git clone https://github.com/martinus/robin-hood-hashing ripser/robinhood - python -m pip install --upgrade pip - python -m pip install --upgrade build - pip install setuptools wheel twine Cython numpy pytest - python -m pip install . - - name: Run tests - run: pytest . - - name: Build and publish - env: - TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} - TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} - run: | - python -m build - twine upload --skip-existing dist/* - - deploy-windows-pip: - strategy: - fail-fast: false - matrix: - arch: ["x86", "x64"] - python-version: ["3.9", "3.10", "3.11", "3.12"] - - runs-on: "windows-latest" - - steps: - - uses: actions/checkout@v2 - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - architecture: ${{ matrix.arch }} - - name: Install dependencies - run: | - git clone https://github.com/martinus/robin-hood-hashing ripser/robinhood - python -m pip install --upgrade pip - python -m pip install --upgrade build - pip install setuptools wheel twine Cython numpy pytest - python -m pip install . - - name: Run tests - run: pytest . - - name: Build and publish - env: - TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} - TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} - run: | - python -m build - twine upload --skip-existing dist/* diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-tests.yml similarity index 56% rename from .github/workflows/python-app.yml rename to .github/workflows/python-tests.yml index ceb22b9..6ee6921 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-tests.yml @@ -5,9 +5,9 @@ name: Test project on: push: - branches: [ master ] + branches: [master] pull_request: - branches: [ master ] + branches: [master] jobs: test: @@ -18,29 +18,29 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - git clone https://github.com/martinus/robin-hood-hashing ripser/robinhood - python -m pip install --upgrade pip - pip install flake8 pytest-cov Cython - pip install -e ".[testing]" - - name: Lint with flake8 - run: | - # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - - name: Test with pytest - run: | - pytest --cov ripser - - name: Upload coverage results - run: | - bash <(curl -s https://codecov.io/bash) + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + git clone https://github.com/martinus/robin-hood-hashing ripser/robinhood + python -m pip install --upgrade pip + pip install flake8 pytest-cov Cython + pip install -e ".[testing]" + - name: Lint with flake8 + run: | + # stop the build if there are Python syntax errors or undefined names + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - name: Test with pytest + run: | + pytest --cov ripser + - name: Upload coverage results + run: | + bash <(curl -s https://codecov.io/bash) test-conda: runs-on: macos-latest @@ -50,18 +50,18 @@ jobs: python-version: ["3.9", "3.10", "3.11", "3.12"] steps: - - uses: actions/checkout@v2 - - uses: conda-incubator/setup-miniconda@v2 + - uses: actions/checkout@v4 + - uses: conda-incubator/setup-miniconda@v3 with: auto-update-conda: true python-version: ${{ matrix.python-version }} activate-environment: test - name: Set up conda shell: bash -l {0} - run: | + run: | conda install git numpy pandas scipy matplotlib pytest cython git clone https://github.com/martinus/robin-hood-hashing ripser/robinhood - python setup.py install + python -m pip install . - name: Test with pytest shell: bash -l {0} run: | @@ -75,19 +75,19 @@ jobs: python-version: ["3.9", "3.10", "3.11", "3.12"] steps: - - uses: actions/checkout@v2 - - uses: conda-incubator/setup-miniconda@v2 + - uses: actions/checkout@v4 + - uses: conda-incubator/setup-miniconda@v3 with: auto-update-conda: true python-version: ${{ matrix.python-version }} activate-environment: test - name: Set up conda shell: bash -l {0} - run: | + run: | echo -e "[build]\ncompiler=msvc\n" >> setup.cfg conda install git numpy pandas scipy matplotlib pytest libpython cython git clone https://github.com/martinus/robin-hood-hashing ripser/robinhood - python setup.py install + python -m pip install . - name: Test with pytest shell: bash -l {0} run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index 7711d2f..4fb420d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,15 @@ -# 0.6.7 +# 0.6.8 - Update CD commands for newer build system. +# 0.6.7 + + - Failed to build wheels. This version does not exist. + +# 0.6.6 + + - Failed to build wheels. This version does not exist. + # 0.6.5 - Bugfix for lower star filtrations with edges that come in at exactly 0 (courtesy of Riccardo Ceccaroni) diff --git a/ripser/_version.py b/ripser/_version.py index f6104e0..afd45a4 100644 --- a/ripser/_version.py +++ b/ripser/_version.py @@ -1 +1 @@ -__version__ = "0.6.7" +__version__ = "0.6.8" diff --git a/setup.py b/setup.py index 5f44f2f..59adbdf 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,8 @@ ## Get version information from _version.py import re -VERSIONFILE="ripser/_version.py" + +VERSIONFILE = "ripser/_version.py" verstrline = open(VERSIONFILE, "rt").read() VSRE = r"^__version__ = ['\"]([^'\"]*)['\"]" mo = re.search(VSRE, verstrline, re.M) @@ -25,63 +26,58 @@ else: raise RuntimeError("Unable to find version string in %s." % (VERSIONFILE,)) -# Use README.md as the package long description -with open('README.md') as f: +# Use README.md as the package long description +with open("README.md") as f: long_description = f.read() + class CustomBuildExtCommand(build_ext): - """ This extension command lets us not require numpy be installed before running pip install ripser - build_ext command for use when numpy headers are needed. + """This extension command lets us not require numpy be installed before running pip install ripser + build_ext command for use when numpy headers are needed. """ def run(self): # Import numpy here, only when headers are needed import numpy + # Add numpy headers to include_dirs self.include_dirs.append(numpy.get_include()) # Call original build_ext command build_ext.run(self) + extra_compile_args = ["-Ofast", "-D_hypot=hypot"] extra_link_args = [] if platform.system() == "Windows": - extra_compile_args.extend([ - # Supported by Visual C++ >=14.1 - '/std:c++14' - ]) + extra_compile_args.extend( + [ + # Supported by Visual C++ >=14.1 + "/std:c++14" + ] + ) elif platform.system() == "Darwin": - extra_compile_args.extend([ - '-std=c++11', - "-mmacosx-version-min=10.9" - ]) - extra_link_args.extend([ - "-stdlib=libc++", - "-mmacosx-version-min=10.9" - ]) + extra_compile_args.extend(["-std=c++11", "-mmacosx-version-min=10.9"]) + extra_link_args.extend(["-stdlib=libc++", "-mmacosx-version-min=10.9"]) else: - extra_compile_args.extend([ - "-std=c++11" - ]) + extra_compile_args.extend(["-std=c++11"]) -macros = [ - ("USE_COEFFICIENTS", 1), - ("NDEBUG", 1), - ("ASSEMBLE_REDUCTION_MATRIX", 1) -] +macros = [("USE_COEFFICIENTS", 1), ("NDEBUG", 1), ("ASSEMBLE_REDUCTION_MATRIX", 1)] # Robinhood -robinhood_path = os.path.join('ripser', 'robinhood') +robinhood_path = os.path.join("ripser", "robinhood") if os.path.isdir(robinhood_path): macros.extend([("USE_ROBINHOOD_HASHMAP", 1)]) - robinhood_include_path = os.path.join('src', 'include') + robinhood_include_path = os.path.join("src", "include") if platform.system() == "Windows": - extra_compile_args.extend(['/I'+os.path.join(robinhood_path, - robinhood_include_path)]) + extra_compile_args.extend( + ["/I" + os.path.join(robinhood_path, robinhood_include_path)] + ) else: - extra_compile_args.extend(['-I'+os.path.join(robinhood_path, - robinhood_include_path)]) + extra_compile_args.extend( + ["-I" + os.path.join(robinhood_path, robinhood_include_path)] + ) ext_modules = Extension( "pyRipser", @@ -89,7 +85,7 @@ def run(self): define_macros=macros, extra_compile_args=extra_compile_args, extra_link_args=extra_link_args, - language="c++" + language="c++", ) @@ -102,43 +98,32 @@ def run(self): author="Chris Tralie, Nathaniel Saul", author_email="chris.tralie@gmail.com, nat@riverasaul.com", url="https://ripser.scikit-tda.org", - license='MIT', - packages=['ripser'], + license="MIT", + packages=["ripser"], ext_modules=cythonize(ext_modules), - install_requires=[ - 'Cython', - 'numpy', - 'scipy', - 'scikit-learn', - 'persim' - ], + install_requires=["Cython", "numpy", "scipy", "scikit-learn", "persim"], extras_require={ - 'testing': [ # `pip install -e ".[testing]"`` - 'pytest' + "testing": [ # `pip install -e ".[testing]"`` + "pytest" ], - 'docs': [ # `pip install -e ".[docs]"` - 'sktda_docs_config' + "docs": [ # `pip install -e ".[docs]"` + "sktda_docs_config" ], - 'examples': [ - 'persim', - 'tadasets', - 'jupyter', - 'pillow' - ] + "examples": ["persim", "tadasets", "jupyter", "pillow"], }, - cmdclass={'build_ext': CustomBuildExtCommand}, - python_requires='>=3.6', + cmdclass={"build_ext": CustomBuildExtCommand}, + python_requires=">=3.6", classifiers=[ - 'Intended Audience :: Science/Research', - 'Intended Audience :: Education', - 'Intended Audience :: Financial and Insurance Industry', - 'Intended Audience :: Healthcare Industry', - 'Topic :: Scientific/Engineering :: Information Analysis', - 'Topic :: Scientific/Engineering :: Mathematics', - 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8' + "Intended Audience :: Science/Research", + "Intended Audience :: Education", + "Intended Audience :: Financial and Insurance Industry", + "Intended Audience :: Healthcare Industry", + "Topic :: Scientific/Engineering :: Information Analysis", + "Topic :: Scientific/Engineering :: Mathematics", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", ], - keywords='persistent homology, rips filtration, persistence diagrams, topology data analysis, algebraic topology, unsupervised learning' + keywords="persistent homology, rips filtration, persistence diagrams, topology data analysis, algebraic topology, unsupervised learning", )