diff --git a/.github/workflows/pypi-deploy.yml b/.github/workflows/pypi-deploy.yml new file mode 100644 index 0000000..49f6fdd --- /dev/null +++ b/.github/workflows/pypi-deploy.yml @@ -0,0 +1,59 @@ +name: Build and upload to PyPI + +on: + workflow_dispatch: + +jobs: + build_wheels: + name: Build wheels on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + # macos-13 is an intel runner, macos-14 is apple silicon + os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, macos-13, macos-14] + + steps: + - uses: actions/checkout@v4 + + - name: Build wheels + uses: pypa/cibuildwheel@v2.22.0 + + - 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: + needs: [build_wheels, build_sdist] + runs-on: ubuntu-latest + environment: pypi + permissions: + id-token: write + #if: github.event_name == 'release' && github.event.action == 'published' + # or, alternatively, upload to PyPI on every tag starting with 'v' (remove on: release above to use this) + # 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 + #with: + # To test: repository-url: https://test.pypi.org/legacy/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b8cb93..a696f17 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,13 +44,13 @@ message(STATUS "PYTHON_BINDINGS: ${PYTHON_BINDINGS}") # Ensure fmt is compiled with -fPIC set_target_properties(fmt PROPERTIES POSITION_INDEPENDENT_CODE ON) - pybind11_add_module(_bindings ./src/pyaccft/_bindings.cpp) + pybind11_add_module(_bindings ./src/pycft/_bindings.cpp) target_link_libraries(_bindings PUBLIC fmt::fmt ${LIBRARIES}) # enable compilation warnings target_compile_options( _bindings PRIVATE "$<$:-Wall>") target_compile_definitions(_bindings PRIVATE PYBIND11_DETAILED_ERROR_MESSAGES) - install(TARGETS _bindings DESTINATION ./src/pyaccft/) + install(TARGETS _bindings DESTINATION ./src/pycft/) endif() ######################################## diff --git a/README.py.md b/README.py.md index e0ffc30..7e6b9df 100644 --- a/README.py.md +++ b/README.py.md @@ -22,7 +22,7 @@ To use the `SetCoverSolver`, first create an instance of the solver. You can the Here is an example: ```python -from pyaccft import SetCoverSolver +from pycft import SetCoverSolver solver = SetCoverSolver() # Add sets with their respective costs diff --git a/pyproject.toml b/pyproject.toml index 35cee52..f9b000d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,6 +6,6 @@ requires = [ "setuptools", "scikit-build>=0.17.3", "cmake>=3.23", - "ninja", + "ninja>=1.11.1.3", ] build-backend = "setuptools.build_meta" \ No newline at end of file diff --git a/setup.py b/setup.py index c300e55..304198f 100644 --- a/setup.py +++ b/setup.py @@ -17,11 +17,11 @@ def readme(): setup( # https://scikit-build.readthedocs.io/en/latest/usage.html#setup-options - name="pyaccft", + name="pycft", version="0.0.1", - author="TODO", + author="Francesco Cavaliere and Dominik Krupke", license="LICENSE", - description="Pybinding for accft", + description="Python-Bindings for the C++-based Set Cover Algorithm CFT.", long_description=readme(), long_description_content_type="text/markdown", packages=find_packages("src"), # Include all packages in `./src`. diff --git a/src/pyaccft/__init__.py b/src/pycft/__init__.py similarity index 100% rename from src/pyaccft/__init__.py rename to src/pycft/__init__.py diff --git a/src/pyaccft/_bindings.cpp b/src/pycft/_bindings.cpp similarity index 100% rename from src/pyaccft/_bindings.cpp rename to src/pycft/_bindings.cpp diff --git a/src/pyaccft/set_cover_solver.py b/src/pycft/set_cover_solver.py similarity index 99% rename from src/pyaccft/set_cover_solver.py rename to src/pycft/set_cover_solver.py index 3d1f7b4..d47876e 100644 --- a/src/pyaccft/set_cover_solver.py +++ b/src/pycft/set_cover_solver.py @@ -27,7 +27,7 @@ class SetCoverSolver: Example: ```python - from pyaccft import SetCoverSolver + from pycft import SetCoverSolver solver = SetCoverSolver() # Set 0 diff --git a/src/utils/Span.hpp b/src/utils/Span.hpp index fdf2f7f..d011722 100644 --- a/src/utils/Span.hpp +++ b/src/utils/Span.hpp @@ -5,8 +5,6 @@ #define CFT_SRC_CORE_SPAN_HPP -#include - #include #include diff --git a/test/test_basics.py b/test/test_basics.py index 65ac226..29c276a 100644 --- a/test/test_basics.py +++ b/test/test_basics.py @@ -1,12 +1,12 @@ # SPDX-FileCopyrightText: 2025 Dominik Krupke # SPDX-License-Identifier: MIT -import pyaccft +import pycft import pytest def test_simple(): - solver = pyaccft.SetCoverSolver() + solver = pycft.SetCoverSolver() # solver.from_file("instances/rail/rail507", "RAIL") solver.add_set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], cost=10) solver.add_set([0, 1, 2, 3, 4, 5], cost=5) @@ -22,7 +22,7 @@ def test_simple(): def test_simple_infeasible(): - solver = pyaccft.SetCoverSolver() + solver = pycft.SetCoverSolver() # solver.from_file("instances/rail/rail507", "RAIL") solver.add_set([0, 1, 2, 3, 4, 5, 6, 8, 9], cost=10) solver.add_set([0, 1, 2, 3, 4, 5], cost=5) @@ -33,19 +33,19 @@ def test_simple_infeasible(): def test_error_on_negative_cost(): - solver = pyaccft.SetCoverSolver() + solver = pycft.SetCoverSolver() with pytest.raises(ValueError): solver.add_set([0, 1, 2, 3, 4, 5, 6, 8, 9], cost=-10) def test_error_on_negative_element(): - solver = pyaccft.SetCoverSolver() + solver = pycft.SetCoverSolver() with pytest.raises(ValueError): solver.add_set([-1, 1, 2, 3, 4, 5, 6, 8, 9], cost=10) def test_simple_incremental(): - solver = pyaccft.SetCoverSolver() + solver = pycft.SetCoverSolver() # solver.from_file("instances/rail/rail507", "RAIL") solver.add_set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], cost=10) solver.add_set([0, 1, 2, 3, 4, 5], cost=5) @@ -65,7 +65,7 @@ def test_simple_incremental(): def test_simple_incremental_new_element(): - solver = pyaccft.SetCoverSolver() + solver = pycft.SetCoverSolver() # solver.from_file("instances/rail/rail507", "RAIL") solver.add_set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], cost=10) solver.add_set([0, 1, 2, 3, 4, 5], cost=5)