Skip to content

Release Python Package to PyPI #116

Release Python Package to PyPI

Release Python Package to PyPI #116

name: Release Python Package to PyPI
on:
release:
types: [published]
workflow_dispatch:
jobs:
build-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:
strategy:
matrix:
include:
- os: windows
runner: windows-latest
arch: x64
python-version: '3.8'
python-tag: 'cp38-cp38'
- os: windows
runner: windows-latest
arch: x64
python-version: '3.9'
python-tag: 'cp39-cp39'
- os: windows
runner: windows-latest
arch: x64
python-version: '3.10'
python-tag: 'cp310-cp310'
- os: windows
runner: windows-latest
arch: x64
python-version: '3.11'
python-tag: 'cp311-cp311'
- os: macos
runner: macos-latest
arch: arm64
python-version: '3.8'
python-tag: 'cp38-cp38'
- os: macos
runner: macos-latest
arch: arm64
python-version: '3.9'
python-tag: 'cp39-cp39'
- os: macos
runner: macos-latest
arch: arm64
python-version: '3.10'
python-tag: 'cp310-cp310'
- os: macos
runner: macos-latest
arch: arm64
python-version: '3.11'
python-tag: 'cp311-cp311'
runs-on: ${{ matrix.runner }}
env:
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: Setup Python
if: runner.os != 'Linux'
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Set macOS Deployment Target
if: runner.os == 'macOS'
run: export MACOSX_DEPLOYMENT_TARGET=14.0
- name: Install Dependencies (Windows)
if: runner.os == 'Windows'
run: choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System' --yes
- name: Setup pip (non-Linux)
if: runner.os != 'Linux'
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine cython numpy
- name: Clean old build directories
shell: bash
run: |
mkdir -p "${{ env.CMAKE_TEMP_DIR }}"
cp -a build_tools/extern/. pmma/extern/
- name: Configure CMake (non-Linux)
if: runner.os != 'Linux'
run: |
if [[ "${{ runner.os }}" == "macOS" ]]; then
export MACOSX_DEPLOYMENT_TARGET=14.0
export CFLAGS="-arch arm64"
export CXXFLAGS="-arch arm64"
cmake -S build_tools/cmake -B ${{ env.CMAKE_TEMP_DIR }} -DCMAKE_OSX_ARCHITECTURES=${{ matrix.arch }}
else
cmake -S build_tools/cmake -B ${{ env.CMAKE_TEMP_DIR }}
fi
shell: bash
- name: Build Shared Library (MacOS)
if: runner.os == 'macOS'
run: |
cmake --build ${{ env.CMAKE_TEMP_DIR }} --config Release -- -j$(sysctl -n hw.ncpu)
find ${{ env.LIB_DIR }} -mindepth 2 -type f -exec mv -t ${{ env.LIB_DIR }} {} +
rm -rf ${{ env.CMAKE_TEMP_DIR }}
shell: bash
- name: Build Shared Library (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
cmake --build "$env:CMAKE_TEMP_DIR" --config Release -- /m
- name: Build Wheel (non-Linux)
if: runner.os != 'Linux'
run: |
python setup.py build_ext --build-lib ${{ env.BUILD_DIR }} --build-temp ${{ env.TEMP_DIR }} sdist bdist_wheel
- name: Upload wheel
uses: actions/upload-artifact@v4
with:
name: wheel-${{ runner.os }}-${{ matrix.python-version }}-${{ matrix.arch }}
path: dist/*.whl
sdist:
name: Build Source Distribution
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
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
runs-on: ubuntu-latest
needs: [build, sdist, build-linux]
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
path: ./artifacts
- name: Move distribution files to expected location
run: |
mkdir -p dist
find artifacts -type f \( -name "*.whl" -o -name "*.tar.gz" \) -exec mv {} dist/ \;
- name: Publish all wheels and sdist
uses: pypa/gh-action-pypi-publish@v1.4.2
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
packages_dir: dist
- name: Upload wheels and sdist to GitHub Release
if: github.event_name == 'release'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
UPLOAD_URL: ${{ github.event.release.upload_url }}
run: |
for file in dist/*; do
filename=$(basename "$file")
echo "Uploading $filename ..."
upload_url="${UPLOAD_URL%\{*}"
curl \
-X POST \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Content-Type: application/octet-stream" \
--data-binary @"$file" \
"$upload_url?name=$filename"
done