diff --git a/.github/workflows/build-wheels.yml b/.github/workflows/build-wheels.yml index e96f934..fa338e1 100644 --- a/.github/workflows/build-wheels.yml +++ b/.github/workflows/build-wheels.yml @@ -5,6 +5,7 @@ on: branches: [main, master] pull_request: workflow_dispatch: + workflow_call: jobs: build_wheel: @@ -19,7 +20,6 @@ jobs: with: fetch-depth: 0 - # Checkout CFD C library - name: Checkout CFD C library uses: actions/checkout@v4 with: @@ -58,10 +58,8 @@ jobs: env: CFD_ROOT: ${{ github.workspace }}/cfd CFD_STATIC_LINK: "ON" + CFD_USE_STABLE_ABI: "ON" run: | - echo "CFD_ROOT=$CFD_ROOT" - echo "Checking CFD library location..." - ls -la $CFD_ROOT/build/lib/ || echo "Library dir not found" pip wheel . --no-deps --wheel-dir dist/ echo "=== Wheel built ===" ls -la dist/ @@ -71,10 +69,8 @@ jobs: env: CFD_ROOT: ${{ github.workspace }}/cfd CFD_STATIC_LINK: "ON" + CFD_USE_STABLE_ABI: "ON" run: | - echo "CFD_ROOT=$env:CFD_ROOT" - echo "Checking CFD library location..." - dir "$env:CFD_ROOT\build\lib\Release" pip wheel . --no-deps --wheel-dir dist/ echo "=== Wheel built ===" dir dist @@ -129,24 +125,6 @@ jobs: pip install (Get-ChildItem dist/*.whl).FullName pip install pytest numpy - - name: Debug Windows DLL (Windows) - if: runner.os == 'Windows' - run: | - # Find package directory via pip - $pkg_dir = python -c "import sysconfig; print(sysconfig.get_paths()['purelib'])" - $pkg_dir = "$pkg_dir\cfd_python" - echo "Package directory: $pkg_dir" - dir $pkg_dir - # Check what the .pyd file depends on - $pyd_file = Get-ChildItem "$pkg_dir\*.pyd" | Select-Object -First 1 - echo "PYD file: $pyd_file" - if ($pyd_file) { - # Use dumpbin to show dependencies - $dumpbin = Get-ChildItem "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\*\bin\Hostx64\x64\dumpbin.exe" | Select-Object -First 1 - echo "Using dumpbin: $dumpbin" - & $dumpbin.FullName /dependents $pyd_file.FullName - } - - name: Test import (Unix) if: runner.os != 'Windows' run: | @@ -166,7 +144,6 @@ jobs: cd $env:TEMP python -c "import cfd_python; print('Package loaded:', cfd_python.__file__); print('Version:', cfd_python.__version__); print('Has list_solvers:', hasattr(cfd_python, 'list_solvers')); print('Solvers:', cfd_python.list_solvers()) if hasattr(cfd_python, 'list_solvers') else None" - # Checkout only tests directory for running tests - uses: actions/checkout@v4 with: sparse-checkout: tests diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..9d27d5e --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,147 @@ +name: Publish to PyPI + +on: + release: + types: [published] + push: + tags: + - 'v*' + workflow_dispatch: + inputs: + target: + description: 'Publish target' + required: true + default: 'testpypi' + type: choice + options: + - testpypi + - pypi + +# Prevent duplicate runs when release creates a tag +concurrency: + group: publish-${{ github.ref }} + cancel-in-progress: false + +jobs: + build: + uses: ./.github/workflows/build-wheels.yml + + build_sdist: + name: Build source distribution + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install build dependencies + run: | + python -m pip install --upgrade pip + pip install build setuptools-scm + + - name: Build sdist + run: python -m build --sdist + + - name: Upload sdist + uses: actions/upload-artifact@v4 + with: + name: sdist + path: dist/*.tar.gz + + publish_testpypi: + name: Publish to TestPyPI + needs: [build, build_sdist] + runs-on: ubuntu-latest + if: github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'testpypi' + environment: + name: testpypi + url: https://test.pypi.org/p/cfd-python + permissions: + id-token: write + contents: read + + steps: + - name: Download wheels + uses: actions/download-artifact@v4 + with: + pattern: wheel-* + path: dist + merge-multiple: true + + - name: Download sdist + uses: actions/download-artifact@v4 + with: + name: sdist + path: dist + + - name: Validate artifacts + run: | + echo "=== Artifacts ===" + ls -la dist/ + WHEELS=$(ls dist/*.whl 2>/dev/null | wc -l) + SDIST=$(ls dist/*.tar.gz 2>/dev/null | wc -l) + echo "Found $WHEELS wheel(s) and $SDIST sdist(s)" + if [ "$WHEELS" -lt 3 ]; then + echo "ERROR: Expected at least 3 wheels (linux, macos, windows), found $WHEELS" + exit 1 + fi + if [ "$SDIST" -lt 1 ]; then + echo "ERROR: Expected at least 1 sdist, found $SDIST" + exit 1 + fi + + - name: Publish to TestPyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ + + publish_pypi: + name: Publish to PyPI + needs: [build, build_sdist] + runs-on: ubuntu-latest + if: github.event_name == 'release' || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) || (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'pypi') + environment: + name: pypi + url: https://pypi.org/p/cfd-python + permissions: + id-token: write + contents: read + + steps: + - name: Download wheels + uses: actions/download-artifact@v4 + with: + pattern: wheel-* + path: dist + merge-multiple: true + + - name: Download sdist + uses: actions/download-artifact@v4 + with: + name: sdist + path: dist + + - name: Validate artifacts + run: | + echo "=== Artifacts ===" + ls -la dist/ + WHEELS=$(ls dist/*.whl 2>/dev/null | wc -l) + SDIST=$(ls dist/*.tar.gz 2>/dev/null | wc -l) + echo "Found $WHEELS wheel(s) and $SDIST sdist(s)" + if [ "$WHEELS" -lt 3 ]; then + echo "ERROR: Expected at least 3 wheels (linux, macos, windows), found $WHEELS" + exit 1 + fi + if [ "$SDIST" -lt 1 ]; then + echo "ERROR: Expected at least 1 sdist, found $SDIST" + exit 1 + fi + + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1