Skip to content

Merge pull request #300 from bgilbert/release #352

Merge pull request #300 from bgilbert/release

Merge pull request #300 from bgilbert/release #352

Workflow file for this run

name: Python
on:
push:
branches: [main]
tags: ["*"]
pull_request:
branches: [main]
permissions:
contents: read
env:
PYTHONUNBUFFERED: 1
jobs:
pre-commit:
name: Rerun pre-commit checks
runs-on: ubuntu-latest
outputs:
dist-base: ${{ steps.paths.outputs.dist }}
docs-base: ${{ steps.paths.outputs.docs }}
steps:
- name: Check out repo
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.13'
- name: Run pre-commit hooks
uses: pre-commit/[email protected]
- name: Define artifact paths
id: paths
run: |
suffix="$GITHUB_RUN_NUMBER-$(echo $GITHUB_SHA | cut -c-10)"
echo "dist=openslide-python-dist-$suffix" >> $GITHUB_OUTPUT
echo "docs=openslide-python-docs-$suffix" >> $GITHUB_OUTPUT
tests:
name: Tests
needs: pre-commit
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, ubuntu-24.04-aarch64, macos-latest]
python-version: [3.8, 3.9, "3.10", "3.11", "3.12", "3.13"]
openslide: [system, wheel]
include:
- os: ubuntu-latest
python-version: "3.13"
openslide: system
sdist: sdist
# Python 3.8 is too old to support universal binaries, and
# setup-python's Python 3.9 and 3.10 won't build them. Use the
# last upstream patch releases that ship with installers.
# https://github.com/actions/setup-python/issues/439#issuecomment-1247646682
- os: macos-latest
python-version: "3.9"
upstream-python: 3.9.13
- os: macos-latest
python-version: "3.10"
upstream-python: 3.10.11
steps:
- name: Check out repo
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
if: matrix.upstream-python == null
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Set up Python ${{ matrix.python-version }} (macOS fallback)
if: matrix.upstream-python != null
run: |
pkgdir="${{ runner.temp }}/python"
mkdir -p "$pkgdir/bin"
pkg="$pkgdir/python.pkg"
curl -Lfo "$pkg" \
"https://www.python.org/ftp/python/${{ matrix.upstream-python }}/python-${{ matrix.upstream-python }}-macos11.pkg"
sudo installer -pkg "$pkg" -target /
for bin in python pip; do
ln -s /usr/local/bin/${bin}3 $pkgdir/bin/${bin}
done
export PATH="$pkgdir/bin:$PATH"
echo "PATH=$PATH" >> $GITHUB_ENV
python -V
pip -V
- name: Install Python tools
run: |
python -m pip install --upgrade pip
pip install auditwheel build jinja2 pytest
- name: Install OpenSlide (system)
if: matrix.openslide == 'system'
run: |
case "${{ matrix.os }}" in
ubuntu-latest)
echo OS_ARCH_TAG=linux-x86_64 >> $GITHUB_ENV
sudo apt-get install libopenslide0
;;
ubuntu-24.04-aarch64)
echo OS_ARCH_TAG=linux-aarch64 >> $GITHUB_ENV
sudo apt-get install libopenslide0
;;
macos-latest)
echo OS_ARCH_TAG=macos-arm64-x86_64 >> $GITHUB_ENV
echo DYLD_LIBRARY_PATH=/opt/homebrew/lib >> $GITHUB_ENV
brew install openslide
;;
esac
- name: Install OpenSlide (wheel)
if: matrix.openslide == 'wheel'
run: pip install openslide-bin
- name: Build dist
run: |
if [ -z "${{ matrix.sdist }}" ]; then
wheel_only=-w
fi
python -m build $wheel_only
case "${{ matrix.os }}" in
ubuntu-*)
mkdir old
mv dist/*.whl old/
auditwheel repair --only-plat -w dist old/*whl
;;
macos-*)
if [ "${{ matrix.python-version }}" != 3.8 -a ! -e dist/*universal2* ]; then
echo "Wheel is not universal:"
ls dist
exit 1
fi
esac
if [ -z "$wheel_only" ]; then
mkdir -p "artifacts/src/${{ needs.pre-commit.outputs.dist-base }}"
mv dist/*.tar.gz "artifacts/src/${{ needs.pre-commit.outputs.dist-base }}"
fi
mkdir -p "artifacts/whl/${{ needs.pre-commit.outputs.dist-base }}"
mv dist/* "artifacts/whl/${{ needs.pre-commit.outputs.dist-base }}"
# from system builds, save version-specific wheels and oldest abi3 wheel
python -c 'import sys
if sys.version_info < (3, 12) and "${{ matrix.openslide }}" == "system":
print("archive_wheel=1")' >> $GITHUB_ENV
- name: Install
run: pip install artifacts/whl/${{ needs.pre-commit.outputs.dist-base }}/*.whl
- name: Run tests
run: pytest -v
- name: Tile slide
run: python examples/deepzoom/deepzoom_tile.py --viewer -o tiled tests/fixtures/small.svs
- name: Archive sdist
if: matrix.sdist
uses: actions/upload-artifact@v4
with:
name: ${{ needs.pre-commit.outputs.dist-base }}-source
path: artifacts/src
compression-level: 0
- name: Archive wheel
if: env.archive_wheel
uses: actions/upload-artifact@v4
with:
name: ${{ needs.pre-commit.outputs.dist-base }}-${{ env.OS_ARCH_TAG }}-${{ matrix.python-version }}
path: artifacts/whl
compression-level: 0
windows:
name: Windows
needs: pre-commit
runs-on: windows-latest
defaults:
run:
shell: bash
strategy:
matrix:
python-version: [3.8, 3.9, "3.10", "3.11", "3.12", "3.13"]
openslide: [zip, wheel]
steps:
- name: Check out repo
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Python tools
run: |
python -m pip install --upgrade pip
pip install build flask pytest
- name: Install OpenSlide (zip)
if: matrix.openslide == 'zip'
env:
GH_TOKEN: ${{ github.token }}
run: |
mkdir -p c:\\openslide
cd c:\\openslide
release=$(gh release list -R openslide/openslide-bin -L 1 \
--json tagName --exclude-drafts --exclude-pre-releases | \
jq -r .[0].tagName | \
tr -d v)
zipname="openslide-bin-${release}-windows-x64"
gh release download -R openslide/openslide-bin "v${release}" \
--pattern "${zipname}.zip"
7z x ${zipname}.zip
echo "OPENSLIDE_PATH=c:\\openslide\\${zipname}\\bin" >> $GITHUB_ENV
- name: Install OpenSlide (wheel)
if: matrix.openslide == 'wheel'
run: pip install openslide-bin
- name: Build wheel
run: |
python -m build -w
mkdir -p "artifacts/whl/${{ needs.pre-commit.outputs.dist-base }}"
mv dist/*.whl "artifacts/whl/${{ needs.pre-commit.outputs.dist-base }}"
# from zip builds, save version-specific wheels and oldest abi3 wheel
python -c 'import sys
if sys.version_info < (3, 12) and "${{ matrix.openslide }}" == "zip":
print("archive_wheel=1")' >> $GITHUB_ENV
- name: Install
run: pip install artifacts/whl/${{ needs.pre-commit.outputs.dist-base }}/*.whl
- name: Run tests
# Reads OPENSLIDE_PATH
run: pytest -v
- name: Test library loading in examples
# Reads OPENSLIDE_PATH
run: |
python examples/deepzoom/deepzoom_multiserver.py -h >/dev/null
python examples/deepzoom/deepzoom_server.py -h >/dev/null
python examples/deepzoom/deepzoom_tile.py -h >/dev/null
- name: Tile slide
# Reads OPENSLIDE_PATH
run: python examples/deepzoom/deepzoom_tile.py --viewer -o tiled tests/fixtures/small.svs
- name: Archive wheel
if: env.archive_wheel
uses: actions/upload-artifact@v4
with:
name: ${{ needs.pre-commit.outputs.dist-base }}-windows-x64-${{ matrix.python-version }}
path: artifacts/whl
compression-level: 0
docs:
name: Docs
needs: pre-commit
runs-on: ubuntu-latest
steps:
- name: Check out repo
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.13'
- name: Install Python tools
run: |
python -m pip install --upgrade pip
pip install sphinx
- name: Build
run: sphinx-build -d doctrees doc artifact/${{ needs.pre-commit.outputs.docs-base }}
- name: Archive
uses: actions/upload-artifact@v4
with:
name: ${{ needs.pre-commit.outputs.docs-base }}
path: artifact
release:
name: Release
if: github.ref_type == 'tag'
environment:
name: pypi
url: https://pypi.org/p/openslide-python
needs: [pre-commit, tests, windows]
runs-on: ubuntu-latest
concurrency: release-${{ github.ref }}
permissions:
contents: write
id-token: write
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
pattern: "${{ needs.pre-commit.outputs.dist-base }}-*"
merge-multiple: true
- name: Release to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: ${{ needs.pre-commit.outputs.dist-base }}
repository-url: ${{ vars.PYPI_URL }}
- name: Release to GitHub
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
version=$(echo "${{ github.ref_name }}" | sed "s/^v//")
# recompress tarball with xz
gunzip -k "${{ needs.pre-commit.outputs.dist-base }}/openslide-python-${version}.tar.gz"
tar xf "${{ needs.pre-commit.outputs.dist-base }}/openslide-python-${version}.tar"
xz -9 "${{ needs.pre-commit.outputs.dist-base }}/openslide-python-${version}.tar"
# extract changelog
awk -e '/^## / && ok {exit}' \
-e '/^## / {ok=1; next}' \
-e 'ok {print}' \
"openslide-python-$version/CHANGELOG.md" > changes
gh release create --latest --verify-tag \
--repo "${{ github.repository }}" \
--title "OpenSlide Python $version" \
--notes-file changes \
"${{ github.ref_name }}" \
"${{ needs.pre-commit.outputs.dist-base }}/"*