remove License from classifiers #141
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Gradient-Free-Optimizers CI Pipeline | |
| # | |
| # Pipeline Structure: | |
| # 1. Code Quality (gate) - Must pass before anything else runs | |
| # 2. API Smoke Tests (gate) - Fast API freeze tests, must pass before main tests | |
| # 3. Main Tests (parallel): | |
| # - OS Matrix Tests (Ubuntu, macOS, Windows × Python versions) | |
| # - Dependency Isolation Tests (no-sklearn, no-scipy) | |
| # 4. Coverage - Runs after all tests pass | |
| name: CI | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - dev | |
| pull_request: | |
| branches: | |
| - main | |
| - dev | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # =========================================================================== | |
| # STAGE 1: Code Quality (gate) | |
| # =========================================================================== | |
| code-quality: | |
| name: Code Quality | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Install pre-commit | |
| run: python -m pip install --no-cache-dir pre-commit | |
| - name: Get changed files | |
| id: changed-files | |
| run: | | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| CHANGED_FILES=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }} | tr '\n' ' ') | |
| else | |
| CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD | tr '\n' ' ') | |
| fi | |
| echo "CHANGED_FILES=${CHANGED_FILES}" >> $GITHUB_ENV | |
| - name: Print changed files | |
| run: | | |
| echo "Changed files:" && echo "$CHANGED_FILES" | tr ' ' '\n' | |
| - name: Run pre-commit on changed files | |
| run: | | |
| if [ -n "$CHANGED_FILES" ]; then | |
| pre-commit run --color always --files $CHANGED_FILES --show-diff-on-failure | |
| else | |
| echo "No changed files to check." | |
| fi | |
| # =========================================================================== | |
| # STAGE 2: API Smoke Tests (gate) | |
| # =========================================================================== | |
| api-smoke-tests: | |
| name: API Smoke Tests | |
| runs-on: ubuntu-latest | |
| needs: code-quality | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install build | |
| make install | |
| make install-test-requirements | |
| - name: Reinstall in editable mode for coverage | |
| run: pip install -e . | |
| - name: Run API smoke tests | |
| run: >- | |
| python -m pytest tests/test_api/ -v --tb=short -p no:warnings | |
| --cov=gradient_free_optimizers --cov-report= | |
| - name: Rename coverage data | |
| run: mv .coverage .coverage.api-smoke | |
| - name: Upload coverage data | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-api-smoke | |
| path: .coverage.api-smoke | |
| include-hidden-files: true | |
| # =========================================================================== | |
| # STAGE 3a: Main Tests - OS Matrix | |
| # =========================================================================== | |
| test-matrix: | |
| name: Tests (${{ matrix.os }}, py${{ matrix.python-version }}, np${{ matrix.numpy-version }}) | |
| runs-on: ${{ matrix.os }} | |
| needs: api-smoke-tests | |
| strategy: | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] | |
| numpy-version: ["1", "2"] | |
| exclude: | |
| # numpy 1.x not compatible with Python 3.13+ | |
| - python-version: "3.13" | |
| numpy-version: "1" | |
| - python-version: "3.14" | |
| numpy-version: "1" | |
| # pandas 1.x has no pre-built wheel for Python 3.12, source build | |
| # broken since setuptools 81 removed pkg_resources (Feb 2026) | |
| - python-version: "3.12" | |
| numpy-version: "1" | |
| # Reduce macOS/Windows matrix to save CI minutes | |
| - os: macos-latest | |
| numpy-version: "1" | |
| - os: windows-latest | |
| numpy-version: "1" | |
| fail-fast: false | |
| steps: | |
| - name: Checkout code | |
| 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: | | |
| python -m pip install --upgrade pip | |
| python -m pip install build | |
| make install | |
| make install-test-requirements | |
| - name: Install specific numpy/pandas versions | |
| shell: bash | |
| run: | | |
| if [ "${{ matrix.numpy-version }}" = "1" ]; then | |
| python -m pip install "numpy>=1.18.1,<2.0.0" "pandas>=1.0,<2.0" | |
| else | |
| python -m pip install "numpy>=2.0,<3.0" "pandas>=2.0,<3.0" | |
| fi | |
| - name: Reinstall in editable mode for coverage | |
| if: matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest' && matrix.numpy-version == '2' | |
| run: pip install -e . | |
| - name: Run main tests | |
| run: >- | |
| python -m pytest tests/test_main/ -v --tb=short -p no:warnings | |
| ${{ matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest' && matrix.numpy-version == '2' && '--cov=gradient_free_optimizers --cov-report=' || '' }} | |
| - name: Rename coverage data | |
| if: matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest' && matrix.numpy-version == '2' | |
| run: mv .coverage .coverage.test-matrix | |
| - name: Upload coverage data | |
| if: matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest' && matrix.numpy-version == '2' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-test-matrix | |
| path: .coverage.test-matrix | |
| include-hidden-files: true | |
| # =========================================================================== | |
| # STAGE 3b: Dependency Isolation Tests - No sklearn | |
| # =========================================================================== | |
| # TEMPORARILY DISABLED - Re-enable when dependency isolation testing is needed | |
| # test-no-sklearn: | |
| # name: Tests (no sklearn) | |
| # runs-on: ubuntu-latest | |
| # needs: api-smoke-tests | |
| # steps: | |
| # - name: Checkout code | |
| # uses: actions/checkout@v4 | |
| # - name: Set up Python 3.11 | |
| # uses: actions/setup-python@v5 | |
| # with: | |
| # python-version: "3.11" | |
| # - name: Install minimal dependencies (no sklearn) | |
| # run: | | |
| # python -m pip install --upgrade pip | |
| # python -m pip install build numpy pandas pytest | |
| # python -m pip install scipy | |
| # - name: Build and install package | |
| # run: | | |
| # python -m pip install build | |
| # python -m build | |
| # pip install dist/*.whl | |
| # - name: Verify sklearn is NOT installed | |
| # run: | | |
| # python -c " | |
| # import sys | |
| # try: | |
| # import sklearn | |
| # print('ERROR: sklearn is installed but should not be!') | |
| # sys.exit(1) | |
| # except ImportError: | |
| # print('OK: sklearn is not installed') | |
| # " | |
| # - name: Run dependency isolation tests | |
| # run: | | |
| # python -m pytest tests/test_dependencies/test_no_sklearn.py -v --tb=short -p no:warnings | |
| # =========================================================================== | |
| # STAGE 3b: Dependency Isolation Tests - No scipy | |
| # =========================================================================== | |
| test-no-scipy: | |
| name: Tests (no scipy) | |
| runs-on: ubuntu-latest | |
| needs: api-smoke-tests | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Install minimal dependencies (no scipy) | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install build numpy pandas pytest tqdm | |
| - name: Build and install package | |
| run: | | |
| python -m pip install build | |
| python -m build | |
| pip install dist/*.whl | |
| - name: Verify scipy is NOT installed | |
| run: | | |
| python -c " | |
| import sys | |
| try: | |
| import scipy | |
| print('ERROR: scipy is installed but should not be!') | |
| sys.exit(1) | |
| except ImportError: | |
| print('OK: scipy is not installed') | |
| " | |
| - name: Run dependency isolation tests | |
| run: | | |
| python -m pytest tests/test_dependencies/test_no_scipy.py -v --tb=short -p no:warnings | |
| # =========================================================================== | |
| # STAGE 3c: Pure Python Backend (no numpy, no scipy, no C extension) | |
| # =========================================================================== | |
| test-pure-python: | |
| name: Backend (pure Python) | |
| runs-on: ubuntu-latest | |
| needs: api-smoke-tests | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Build and install WITHOUT C extension | |
| env: | |
| GFO_DISABLE_C_EXTENSION: "1" | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install build pytest tqdm setuptools | |
| python -m build | |
| pip install dist/*.whl | |
| pip uninstall numpy pandas scipy -y 2>/dev/null || true | |
| - name: Verify pure Python environment | |
| run: | | |
| python -c " | |
| import sys | |
| errors = [] | |
| for mod in ('numpy', 'scipy'): | |
| try: | |
| __import__(mod) | |
| errors.append(f'{mod} is importable but should not be') | |
| except ImportError: | |
| print(f'OK: {mod} not installed') | |
| from gradient_free_optimizers._array_backend import ( | |
| HAS_NUMPY, HAS_C_EXTENSION, _backend_name, array, | |
| ) | |
| from gradient_free_optimizers._array_backend._pure import GFOArray | |
| if HAS_NUMPY: | |
| errors.append('HAS_NUMPY is True') | |
| if HAS_C_EXTENSION: | |
| errors.append('HAS_C_EXTENSION is True') | |
| if _backend_name != 'pure': | |
| errors.append(f'_backend_name is {_backend_name!r}, expected pure') | |
| a = array([1.0, 2.0]) | |
| if type(a) is not GFOArray: | |
| errors.append(f'array() returned {type(a).__name__}, expected GFOArray') | |
| if errors: | |
| for e in errors: | |
| print(f'FAIL: {e}') | |
| sys.exit(1) | |
| print('OK: pure Python backend verified') | |
| " | |
| - name: Run backend tests (unit + integration + backend verification) | |
| run: | | |
| python -m pytest tests/test_dependencies/test_backend_pure.py -v --tb=short -p no:warnings | |
| # =========================================================================== | |
| # STAGE 3d: C Extension Backend (no numpy, no scipy, with compiled C) | |
| # =========================================================================== | |
| test-c-extension: | |
| name: Backend (C extension) | |
| runs-on: ubuntu-latest | |
| needs: api-smoke-tests | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Build and install WITH C extension | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install build pytest tqdm setuptools | |
| python -m build | |
| pip install dist/*.whl | |
| pip uninstall numpy pandas scipy -y 2>/dev/null || true | |
| - name: Verify C extension environment | |
| run: | | |
| python -c " | |
| import sys | |
| errors = [] | |
| for mod in ('numpy', 'scipy'): | |
| try: | |
| __import__(mod) | |
| errors.append(f'{mod} is importable but should not be') | |
| except ImportError: | |
| print(f'OK: {mod} not installed') | |
| from gradient_free_optimizers._array_backend import ( | |
| HAS_NUMPY, HAS_C_EXTENSION, _backend_name, array, | |
| ) | |
| from gradient_free_optimizers._array_backend._c_extension import _CGFOArray | |
| if HAS_NUMPY: | |
| errors.append('HAS_NUMPY is True') | |
| if not HAS_C_EXTENSION: | |
| errors.append('HAS_C_EXTENSION is False (C extension not compiled)') | |
| if _backend_name != 'c_extension': | |
| errors.append(f'_backend_name is {_backend_name!r}, expected c_extension') | |
| a = array([1.0, 2.0]) | |
| if type(a) is not _CGFOArray: | |
| errors.append(f'array() returned {type(a).__name__}, expected _CGFOArray') | |
| if errors: | |
| for e in errors: | |
| print(f'FAIL: {e}') | |
| sys.exit(1) | |
| print('OK: C extension backend verified') | |
| " | |
| - name: Run C extension unit tests | |
| run: | | |
| python -m pytest tests/test_internal/test_array_backend/test_c_extension.py -v --tb=short -p no:warnings | |
| - name: Run backend tests (unit + integration + backend verification) | |
| run: | | |
| python -m pytest tests/test_dependencies/test_backend_c_extension.py -v --tb=short -p no:warnings | |
| # =========================================================================== | |
| # STAGE 4: Coverage Report (only on Ubuntu with full dependencies) | |
| # =========================================================================== | |
| coverage: | |
| name: Coverage Report | |
| runs-on: ubuntu-latest | |
| needs: [test-matrix, test-no-scipy, test-pure-python, test-c-extension] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Install coverage | |
| run: pip install "coverage[toml]" | |
| - name: Download all coverage data | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: coverage-* | |
| merge-multiple: true | |
| - name: Combine coverage data | |
| run: | | |
| coverage combine | |
| coverage report --show-missing | |
| coverage xml | |
| - name: Upload coverage to Codecov | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: ./coverage.xml | |
| fail_ci_if_error: false | |
| verbose: true |