Skip to content

Build and Publish to PyPI #15

Build and Publish to PyPI

Build and Publish to PyPI #15

Workflow file for this run

name: Build and Publish to PyPI
on:
release:
types: [published]
workflow_dispatch: # Allow manual trigger for testing
env:
GIT_LFS_SKIP_SMUDGE: 1 # Skip LFS to avoid bandwidth quota issues
jobs:
build_wheels:
name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, windows-2022, macos-15]
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "18"
- name: Install quicktype
run: npm install -g quicktype
- name: Install cibuildwheel
run: python -m pip install cibuildwheel==2.21.3
- name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse
env:
# Build for Python 3.10, 3.11, 3.12, 3.13
CIBW_BUILD: cp310-* cp311-* cp312-* cp313-*
# Skip 32-bit builds, musllinux, and PyPy
CIBW_SKIP: "*-win32 *-manylinux_i686 *musllinux* pp*"
# Use manylinux_2_28 (AlmaLinux 8) for C++23 support (GCC 12+ via gcc-toolset)
CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28
# Install Node.js 18 and quicktype in the build container (Linux)
# Also install gcc-toolset-13 for C++23 support
CIBW_BEFORE_ALL_LINUX: |
dnf install -y gcc-toolset-13 && \
source /opt/rh/gcc-toolset-13/enable && \
curl -fsSL https://rpm.nodesource.com/setup_18.x | bash - && \
dnf install -y nodejs && \
npm install -g quicktype
CIBW_BEFORE_ALL_MACOS: npm install -g quicktype
CIBW_BEFORE_ALL_WINDOWS: npm install -g quicktype
# Set macOS deployment target to 15.0 for arm64 (Homebrew libraries require it)
CIBW_ENVIRONMENT_MACOS: MACOSX_DEPLOYMENT_TARGET=15.0
# Enable gcc-toolset-13 before build for C++23
CIBW_ENVIRONMENT_LINUX: PATH=/opt/rh/gcc-toolset-13/root/usr/bin:$PATH LD_LIBRARY_PATH=/opt/rh/gcc-toolset-13/root/usr/lib64:$LD_LIBRARY_PATH
# Install build dependencies
CIBW_BEFORE_BUILD: pip install scikit-build-core cmake ninja pybind11
# Test the wheel
CIBW_TEST_COMMAND: python -c "import PyOpenMagnetics; print(f'PyOpenMagnetics loaded successfully with {len(dir(PyOpenMagnetics))} functions')"
- uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}
path: ./wheelhouse/*.whl
build_sdist:
name: Build source distribution
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "18"
- name: Install quicktype
run: npm install -g quicktype
- name: Install build
run: python -m pip install build
- name: Build sdist
run: python -m build --sdist
- uses: actions/upload-artifact@v4
with:
name: sdist
path: dist/*.tar.gz
publish:
name: Publish to PyPI
needs: [build_wheels, build_sdist]
runs-on: ubuntu-22.04
# Only publish on release
if: github.event_name == 'release'
environment:
name: pypi
url: https://pypi.org/p/pyopenmagnetics
permissions:
id-token: write # Required for trusted publishing
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true
- name: List distribution files
run: ls -la dist/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
# Option 1: Use API token (set PYPI_API_TOKEN in repository secrets)
password: ${{ secrets.PYPI_API_TOKEN }}
# Option 2: Use trusted publishing (no token needed, configure on PyPI)
# Uncomment the line below and remove password above to use trusted publishing
# trusted-publishing: true
# Optional: Publish to TestPyPI first for testing
publish_test:
name: Publish to TestPyPI
needs: [build_wheels, build_sdist]
runs-on: ubuntu-22.04
if: github.event_name == 'workflow_dispatch'
environment:
name: testpypi
url: https://test.pypi.org/p/pyopenmagnetics
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true
- name: Publish to TestPyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
password: ${{ secrets.TEST_PYPI_API_TOKEN }}