Skip to content

Release Python Package to PyPI #130

Release Python Package to PyPI

Release Python Package to PyPI #130

name: Release Python Package to PyPI
on:
release:
types: [published]
workflow_dispatch:
jobs:
# ──────────────────────────────────────
# 1. Build PMMA_Core for each OS once
# ──────────────────────────────────────
build-core-linux:
name: Build Linux wheels (all versions)
runs-on: ubuntu-latest
env:
PYTHON_TAGS: "cp38-cp38 cp39-cp39 cp310-cp310 cp311-cp311"
BUILD_DIR: pmma/build
LIB_DIR: pmma/lib
TEMP_DIR: temporary
CMAKE_TEMP_DIR: temporary/cmake
steps:
- name: Checkout repo
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Ensure dist directory exists
run: mkdir -p dist
- name: Build all Linux wheels in parallel inside Docker
if: runner.os == 'Linux'
run: |
docker run --rm \
-v "${{ github.workspace }}:/PMMA" \
-v "${{ github.workspace }}/dist:/output_dist" \
-e PYTHON_TAGS="cp38-cp38 cp39-cp39 cp310-cp310 cp311-cp311" \
quay.io/pypa/manylinux_2_28_x86_64 \
/bin/bash -c '
set -e
yum install -y cmake make gcc gcc-c++ mesa-libGL-devel libXrandr-devel libXinerama-devel libXcursor-devel libXi-devel wayland-devel libxkbcommon-devel
build_for_python() {
tag=$1
dir="/tmp/build_$tag"
cp -r /PMMA "$dir"
cd "$dir"
mkdir -p pmma/extern
mv build_tools/extern/* pmma/extern/
/opt/python/$tag/bin/python -m pip install --upgrade pip setuptools wheel cython numpy
mkdir -p ${{ env.CMAKE_TEMP_DIR }}
cmake -S build_tools/cmake -B ${{ env.CMAKE_TEMP_DIR }} -DCMAKE_POSITION_INDEPENDENT_CODE=ON
cmake --build ${{ env.CMAKE_TEMP_DIR }} --config Release -- -j$(nproc)
find ${{ env.LIB_DIR }} -mindepth 2 -type f -exec mv -t ${{ env.LIB_DIR }} {} +
rm -rf ${{ env.CMAKE_TEMP_DIR }}
/opt/python/$tag/bin/python setup.py build_ext --build-lib ${{ env.BUILD_DIR }} --build-temp ${{ env.TEMP_DIR }} sdist bdist_wheel
original=$(ls dist/*.whl)
renamed=$(echo "$original" | sed "s/linux/manylinux_2_28/")
mv "$original" "$renamed"
cp dist/* /output_dist/
}
export -f build_for_python
mkdir -p /PMMA/dist
pids=()
for tag in $PYTHON_TAGS; do
bash -c "build_for_python $tag" &
pids+=($!)
done
# Wait for all and fail if any fail
for pid in "${pids[@]}"; do
wait "$pid" || exit 1
done
wait
'
- name: Upload all Linux wheels
uses: actions/upload-artifact@v4
with:
name: wheel-linux-all
path: dist/*.whl
build-core-macos:
name: Build native library (macOS arm64)
runs-on: macos-latest
env:
CMAKE_OSX_ARCHITECTURES: arm64
steps:
- uses: actions/checkout@v3
- name: Install dependencies
run: brew install cmake
- name: Copy pre-configured extern includes
shell: bash
run: |
cp -a build_tools/extern/. pmma/extern/
- name: Configure & build
run: |
export MACOSX_DEPLOYMENT_TARGET=14.0
export CFLAGS="-arch arm64"
export CXXFLAGS="-arch arm64"
cmake -S build_tools/cmake -B temporary -DCMAKE_OSX_ARCHITECTURES=arm64
cmake --build temporary --config Release -- -j$(sysctl -n hw.ncpu)
- name: Clean up build directory
run: rm -rf temporary
- uses: actions/upload-artifact@v4
with:
name: pmma-macos-arm64
path: "${{ github.workspace }}"
build-core-windows:
name: Build native library (Windows x64)
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Install CMake
run: choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System' --yes
- name: Copy pre-configured extern includes
shell: bash
run: |
cp -a build_tools/extern/. pmma/extern/
- name: Configure & build
shell: pwsh
run: |
cmake -S build_tools/cmake -B temporary -DCMAKE_BUILD_TYPE=Release
cmake --build temporary --config Release -- /m
- name: Clean up build directory
shell: pwsh
run: Remove-Item -Recurse -Force temporary
- uses: actions/upload-artifact@v4
with:
name: pmma-windows-x64
path: "${{ github.workspace }}"
# ──────────────────────────────────────
# 2. Python builds per OS/arch via matrix
# ──────────────────────────────────────
build_macos:
needs:
- build-core-macos
strategy:
matrix:
include:
- os: macos
runs-on: macos-latest
pmma_artifact: pmma-macos-arm64
python-version: '3.8'
- os: macos
runs-on: macos-latest
pmma_artifact: pmma-macos-arm64
python-version: '3.9'
- os: macos
runs-on: macos-latest
pmma_artifact: pmma-macos-arm64
python-version: '3.10'
- os: macos
runs-on: macos-latest
pmma_artifact: pmma-macos-arm64
python-version: '3.11'
runs-on: ${{ matrix.runs-on }}
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Download pmma directory artifact
uses: actions/download-artifact@v4
with:
name: ${{ matrix.pmma_artifact }}
path: PMMA
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Setup pip & build tools
run: |
python -m pip install --upgrade pip setuptools wheel cython numpy twine
- name: Build Python wheel
run: |
ls -R
python setup.py build_ext --build-lib pmma/build --build-temp temporary sdist bdist_wheel
- name: Upload wheel
uses: actions/upload-artifact@v4
with:
name: wheel-${{ matrix.os }}-${{ matrix.python-version }}
path: dist/*.whl
build_windows:
needs:
- build-core-windows
strategy:
matrix:
include:
- os: windows
runs-on: windows-latest
pmma_artifact: pmma-windows-x64
python-version: '3.8'
- os: windows
runs-on: windows-latest
pmma_artifact: pmma-windows-x64
python-version: '3.9'
- os: windows
runs-on: windows-latest
pmma_artifact: pmma-windows-x64
python-version: '3.10'
- os: windows
runs-on: windows-latest
pmma_artifact: pmma-windows-x64
python-version: '3.11'
runs-on: ${{ matrix.runs-on }}
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Download pmma directory artifact
uses: actions/download-artifact@v4
with:
name: ${{ matrix.pmma_artifact }}
path: PMMA
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Setup pip & build tools
run: |
python -m pip install --upgrade pip setuptools wheel cython numpy twine
- name: Build Python wheel
run: |
ls -R
python setup.py build_ext --build-lib PMMA/pmma/build --build-temp temporary sdist bdist_wheel
- name: Upload wheel
uses: actions/upload-artifact@v4
with:
name: wheel-${{ matrix.os }}-${{ matrix.python-version }}
path: dist/*.whl
# ──────────────────────────────────────
# 3. sdist and publish
# ──────────────────────────────────────
sdist:
name: Build Source Distribution
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- run: |
pip install setuptools wheel cython numpy
python setup.py sdist
- uses: actions/upload-artifact@v4
with:
name: sdist
path: dist/*.tar.gz
publish:
name: Publish to PyPI + GitHub Release
runs-on: ubuntu-latest
needs: [build_windows, build_macos, sdist, build-core-linux]
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
path: ./artifacts
- name: Move distribution files
run: |
mkdir -p dist
find artifacts -type f \( -name "*.whl" -o -name "*.tar.gz" \) -exec mv {} dist/ \;
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@v1.4.2
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
packages_dir: dist
- name: Upload to GitHub Release
if: github.event_name == 'release'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
UPLOAD_URL: ${{ github.event.release.upload_url }}
run: |
for f in dist/*; do
echo "Uploading $f ..."
curl -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Content-Type: application/octet-stream" \
--data-binary @"$f" \
"${UPLOAD_URL%\{*}?name=$(basename "$f")"
done