Bump version to 3.5.1 for PyPI re-release #62
Workflow file for this run
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
| name: Build Python Wheels | |
| on: | |
| push: | |
| branches: [ main, python ] | |
| tags: | |
| - 'v*' | |
| pull_request: | |
| branches: [ main ] | |
| paths: | |
| - 'python-kalign/**' | |
| - 'lib/**' | |
| - 'CMakeLists.txt' | |
| - 'pyproject.toml' | |
| - '.github/workflows/wheels.yml' | |
| workflow_dispatch: | |
| inputs: | |
| publish_target: | |
| description: "Publish target (manual runs only)" | |
| required: true | |
| default: "none" | |
| type: choice | |
| options: | |
| - none | |
| - testpypi | |
| jobs: | |
| build_wheels: | |
| name: Build wheels on ${{ matrix.os }} (${{ matrix.cibw_archs }}) | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| cibw_archs: "x86_64" | |
| - os: macos-14 | |
| cibw_archs: "x86_64" | |
| - os: macos-14 | |
| cibw_archs: "arm64" | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install cibuildwheel build | |
| - name: Build wheels | |
| env: | |
| CIBW_BUILD: cp39-* cp310-* cp311-* cp312-* cp313-* | |
| CIBW_SKIP: "*-win32 *-manylinux_i686 *-musllinux*" | |
| CIBW_ARCHS: ${{ matrix.cibw_archs }} | |
| # Set minimum macOS version to match OpenMP requirements | |
| CIBW_ENVIRONMENT_MACOS: > | |
| CMAKE_BUILD_PARALLEL_LEVEL=2 | |
| OMP_NUM_THREADS=1 | |
| MACOSX_DEPLOYMENT_TARGET=14.0 | |
| CMAKE_OSX_DEPLOYMENT_TARGET=14.0 | |
| # Linux specific settings - handle different package managers | |
| CIBW_BEFORE_ALL_LINUX: > | |
| (yum install -y cmake3) || | |
| (apt-get update && apt-get install -y cmake) || | |
| (apk add --no-cache cmake) | |
| CIBW_REPAIR_WHEEL_COMMAND_LINUX: auditwheel repair -w {dest_dir} {wheel} | |
| # macOS specific settings | |
| CIBW_BEFORE_ALL_MACOS: | | |
| brew install --formula cmake libomp || echo "Dependencies may already be installed" | |
| CIBW_REPAIR_WHEEL_COMMAND_MACOS: > | |
| delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel} | |
| # Environment variables for builds | |
| CIBW_ENVIRONMENT: > | |
| CMAKE_BUILD_PARALLEL_LEVEL=2 | |
| OMP_NUM_THREADS=1 | |
| # Skip testing during wheel build to avoid cross-compilation issues | |
| CIBW_TEST_SKIP: "*" | |
| run: | | |
| python -m cibuildwheel --output-dir wheelhouse | |
| - name: Upload wheels | |
| 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 | |
| with: | |
| submodules: recursive | |
| - name: Set up Python | |
| 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 | |
| - name: Build sdist | |
| run: | | |
| python -m build --sdist --outdir dist/ | |
| - name: Upload sdist | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: cibw-sdist | |
| path: dist/*.tar.gz | |
| test_install: | |
| name: Test wheel installation | |
| needs: [build_wheels] | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-14] | |
| python-version: ['3.9', '3.10', '3.11', '3.12'] | |
| steps: | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Download wheels | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: cibw-wheels-* | |
| merge-multiple: true | |
| path: wheelhouse/ | |
| - name: Test installation and import | |
| run: | | |
| # Let pip find and install the appropriate wheel | |
| echo "=== Available wheels ===" | |
| ls -la wheelhouse/*.whl | |
| # Determine the distribution name from the wheel filenames (PEP 427) | |
| # e.g. kalign_test-3.4.5-...whl -> kalign-test | |
| DIST_NAME="$(ls wheelhouse/*.whl | head -n 1 | xargs basename | cut -d- -f1 | tr '_' '-')" | |
| echo "=== Detected dist name: ${DIST_NAME} ===" | |
| echo "=== Installing wheel ===" | |
| pip install --find-links wheelhouse/ "${DIST_NAME}" --force-reinstall | |
| # Check what got installed | |
| echo "=== Checking installed packages ===" | |
| pip list | grep -E 'kalign' || true | |
| # Check the kalign module structure | |
| echo "=== Checking kalign module ===" | |
| python -c " | |
| import sys | |
| print('Python version:', sys.version) | |
| print('Attempting to import kalign...') | |
| try: | |
| import kalign | |
| print('✓ kalign imported successfully') | |
| print('kalign location:', kalign.__file__) | |
| import os | |
| kalign_dir = os.path.dirname(kalign.__file__) | |
| print('kalign dir contents:', sorted(os.listdir(kalign_dir))) | |
| # Check for _core specifically | |
| core_files = [f for f in os.listdir(kalign_dir) if '_core' in f] | |
| print('_core files found:', core_files) | |
| except ImportError as e: | |
| print('✗ Import failed:', str(e)) | |
| import os | |
| import site | |
| print('Site packages:', site.getsitepackages()) | |
| for site_dir in site.getsitepackages(): | |
| kalign_path = os.path.join(site_dir, 'kalign') | |
| if os.path.exists(kalign_path): | |
| print(f'Found kalign at {kalign_path}') | |
| print('Contents:', sorted(os.listdir(kalign_path))) | |
| break | |
| sys.exit(1) | |
| " | |
| # Test the installation | |
| python -c " | |
| import kalign | |
| print('kalign version:', kalign.__version__) | |
| # Test basic functionality | |
| sequences = ['ATCGATCG', 'ATCGTCG', 'ATCGATCG'] | |
| aligned = kalign.align(sequences, seq_type='dna') | |
| print('Number of aligned sequences:', len(aligned)) | |
| print('Alignment lengths:', [len(seq) for seq in aligned]) | |
| assert len(aligned) == 3 | |
| assert all(len(seq) == len(aligned[0]) for seq in aligned) | |
| print('✓ Basic alignment test passed') | |
| # Test with different sequence types | |
| protein_seqs = ['MKTAYIAKQRQ', 'MKTAYIAKQ', 'MKTAYIAK'] | |
| aligned_proteins = kalign.align(protein_seqs, seq_type='protein') | |
| print('✓ Protein alignment test passed') | |
| print('All tests passed successfully!') | |
| " | |
| test_ecosystem: | |
| name: Test ecosystem integrations | |
| needs: [build_wheels] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: cibw-wheels-* | |
| merge-multiple: true | |
| path: wheelhouse/ | |
| - name: Install kalign with all extras | |
| run: | | |
| DIST_NAME="$(ls wheelhouse/*.whl | head -n 1 | xargs basename | cut -d- -f1 | tr '_' '-')" | |
| pip install --find-links wheelhouse/ "${DIST_NAME}[all]" --force-reinstall | |
| pip install pytest | |
| - name: Verify ecosystem packages are installed | |
| run: | | |
| python -c "import Bio; print(f'Biopython {Bio.__version__}')" | |
| python -c "import skbio; print(f'scikit-bio {skbio.__version__}')" | |
| python -c "import pandas; print(f'pandas {pandas.__version__}')" | |
| python -c "import matplotlib; print(f'matplotlib {matplotlib.__version__}')" | |
| - name: Run ecosystem tests (fail if any skipped) | |
| run: | | |
| pytest tests/python/test_ecosystem_real.py -v --tb=short 2>&1 | tee test_output.txt | |
| # Fail if any tests were skipped — all ecosystem deps should be present | |
| if grep -q "skipped" test_output.txt; then | |
| echo "ERROR: Some ecosystem tests were skipped — all deps should be installed" | |
| exit 1 | |
| fi | |
| upload_pypi: | |
| name: Upload to PyPI | |
| needs: [build_wheels, build_sdist, test_install, test_ecosystem] | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') | |
| permissions: | |
| id-token: write | |
| environment: | |
| name: pypi | |
| steps: | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: cibw-* | |
| merge-multiple: true | |
| path: dist/ | |
| - name: Publish to PyPI (trusted publishing) | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| with: | |
| packages_dir: dist/ | |
| upload_testpypi: | |
| name: Upload to TestPyPI | |
| needs: [build_wheels, build_sdist, test_install, test_ecosystem] | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'workflow_dispatch' && inputs.publish_target == 'testpypi' | |
| steps: | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: cibw-* | |
| merge-multiple: true | |
| path: dist/ | |
| - name: Publish to TestPyPI (API token) | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| with: | |
| user: __token__ | |
| password: ${{ secrets.TEST_PYPI_API_TOKEN }} | |
| packages_dir: dist/ | |
| repository-url: https://test.pypi.org/legacy/ | |
| verbose: true |