Skip to content

Merge pull request #5 from caiyunapp/ci/release #128

Merge pull request #5 from caiyunapp/ci/release

Merge pull request #5 from caiyunapp/ci/release #128

Workflow file for this run

name: Test
on:
push:
branches: [main, master, develop]
pull_request:
branches: [main, master, develop]
workflow_dispatch:
workflow_call:
jobs:
test-linux:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
container: python:3.12-bookworm
platform: linux_x86_64
arch: x86_64
arch_label: x86_64
- os: ubuntu-24.04-arm
container: python:3.12-bookworm
platform: linux_aarch64
arch: arm64
arch_label: arm64
runs-on: ${{ matrix.os }}
container: ${{ matrix.container }}
env:
UV_LINK_MODE: copy
UV_CACHE_DIR: /github/home/.cache/uv
permissions:
actions: write
contents: read
checks: write
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
submodules: recursive
- name: Cache uv downloads
uses: actions/cache@v5
with:
path: /github/home/.cache/uv
key: uvcache-${{ runner.os }}-${{ matrix.arch_label }}-${{ hashFiles('uv.lock', 'pyproject.toml') }}
restore-keys: |
uvcache-${{ runner.os }}-${{ matrix.arch_label }}-
- name: Cache uv virtual environment and build artifacts
uses: actions/cache@v5
with:
path: .venv
key: venv-${{ runner.os }}-${{ matrix.arch_label }}-${{ hashFiles('uv.lock', 'pyproject.toml', 'setup.py') }}-${{ hashFiles('src/**/*.cpp', 'src/**/*.hpp', 'packaging/**/*.py') }}
restore-keys: |
venv-${{ runner.os }}-${{ matrix.arch_label }}-${{ hashFiles('uv.lock', 'pyproject.toml', 'setup.py') }}-
venv-${{ runner.os }}-${{ matrix.arch_label }}-
- name: Add Debian sid repository
run: |
echo "deb http://deb.debian.org/debian sid main" >> /etc/apt/sources.list.d/sid.list
echo 'Package: *\nPin: release a=sid\nPin-Priority: 100' > /etc/apt/preferences.d/sid
- name: Install system dependencies
run: |
apt-get update
# Ensure /etc/os-release exists (required by some actions' OS detection).
apt-get install -y base-files
# Install build tools and common dependencies
apt-get install -y \
build-essential \
pkg-config \
libbz2-dev \
libssl-dev \
libboost-dev \
libboost-filesystem-dev \
libboost-program-options-dev \
libboost-regex-dev \
libboost-system-dev
# Install Mapnik from sid (version 4.2)
# This will automatically install most dependencies like ICU, Cairo, HarfBuzz, etc.
apt-get install -y -t sid libmapnik-dev
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
# Work around container-job failures determining Linux distribution during
# setup-uv's built-in caching path; we cache UV_CACHE_DIR ourselves above.
enable-cache: false
- name: Install Python dependencies and build package
run: |
# Use lockfile when present; avoid doing two full syncs (which can rebuild twice).
if [ -f uv.lock ]; then
uv sync --extra test --frozen --verbose
else
uv sync --extra test --verbose
fi
- name: Run tests with coverage
run: |
uv run pytest test/python_tests -v \
--cov=mapnik \
--cov-report=term \
--cov-report=xml:coverage.xml \
--cov-report=html:htmlcov \
--junitxml=junit.xml
- name: Upload coverage reports
uses: actions/upload-artifact@v4
if: always()
with:
name: coverage-reports-linux-${{ matrix.arch_label }}
path: |
coverage.xml
htmlcov/
junit.xml
retention-days: 30
- name: Publish test results
uses: EnricoMi/publish-unit-test-result-action@v2
if: always()
with:
files: junit.xml
check_name: Test Results (Linux ${{ matrix.arch_label }})
comment_mode: off
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
if: always()
with:
files: coverage.xml
flags: unittests-linux-${{ matrix.arch_label }}
name: python-mapnik-coverage-linux-${{ matrix.arch_label }}
fail_ci_if_error: false
token: ${{ secrets.CODECOV_TOKEN }}
- name: Build sdist
run: |
uv build --sdist
- name: Upload sdist
uses: actions/upload-artifact@v4
with:
name: sdist-${{ matrix.os }}-${{ matrix.arch_label }}
path: dist/*.tar.gz
retention-days: 7
test-macos:
strategy:
fail-fast: false
matrix:
include:
- os: macos-15-intel
platform: macosx_15_0_x86_64
arch: x86_64
arch_label: x86_64
- os: macos-15
platform: macosx_15_0_arm64
arch: arm64
arch_label: arm64
- os: macos-latest
platform: macosx_15_0_arm64
arch: arm64
arch_label: arm64
runs-on: ${{ matrix.os }}
env:
UV_LINK_MODE: copy
UV_CACHE_DIR: /Users/runner/.cache/uv
permissions:
actions: write
contents: read
checks: write
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
submodules: recursive
- name: Cache uv downloads
uses: actions/cache@v5
with:
path: /Users/runner/.cache/uv
key: uvcache-${{ runner.os }}-${{ matrix.arch_label }}-${{ hashFiles('uv.lock', 'pyproject.toml') }}
restore-keys: |
uvcache-${{ runner.os }}-${{ matrix.arch_label }}-
- name: Cache uv virtual environment and build artifacts
uses: actions/cache@v5
with:
path: .venv
key: venv-${{ runner.os }}-${{ matrix.arch_label }}-${{ hashFiles('uv.lock', 'pyproject.toml', 'setup.py') }}-${{ hashFiles('src/**/*.cpp', 'src/**/*.hpp', 'packaging/**/*.py') }}
restore-keys: |
venv-${{ runner.os }}-${{ matrix.arch_label }}-${{ hashFiles('uv.lock', 'pyproject.toml', 'setup.py') }}-
venv-${{ runner.os }}-${{ matrix.arch_label }}-
- name: Install Homebrew dependencies
run: |
# Install Mapnik which will automatically install all required dependencies
# including boost, cairo, harfbuzz, icu4c, gdal, proj, freetype, and 100+ other packages
brew install mapnik pkg-config
- name: Setup build environment
run: |
# Ensure Homebrew environment is available
eval $(brew shellenv)
# Note: setup.py now auto-detects Homebrew paths for Boost, HarfBuzz, etc.
# We only need to ensure PKG_CONFIG_PATH includes ICU and Mapnik
HOMEBREW_PREFIX=$(brew --prefix)
# Get ICU prefix (could be icu4c@78 or icu4c)
ICU4C_PREFIX=$(brew --prefix icu4c@78 2>/dev/null || brew --prefix icu4c 2>/dev/null || echo "")
MAPNIK_PREFIX=$(brew --prefix mapnik 2>/dev/null || echo "$HOMEBREW_PREFIX/opt/mapnik")
# Set up minimal PKG_CONFIG_PATH (setup.py will handle the rest)
PKG_CONFIG_PATH="$HOMEBREW_PREFIX/lib/pkgconfig:$HOMEBREW_PREFIX/share/pkgconfig"
[ -n "$ICU4C_PREFIX" ] && PKG_CONFIG_PATH="$ICU4C_PREFIX/lib/pkgconfig:$PKG_CONFIG_PATH"
[ -d "$MAPNIK_PREFIX/lib/pkgconfig" ] && PKG_CONFIG_PATH="$MAPNIK_PREFIX/lib/pkgconfig:$PKG_CONFIG_PATH"
echo "PKG_CONFIG_PATH=$PKG_CONFIG_PATH" >> $GITHUB_ENV
# Verify environment
echo "Homebrew prefix: $HOMEBREW_PREFIX"
echo "ICU prefix: $ICU4C_PREFIX"
echo "Mapnik version: $(mapnik-config --version 2>/dev/null || echo 'not found')"
echo "PKG_CONFIG_PATH: $PKG_CONFIG_PATH"
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: false
- name: Install Python dependencies and build package
run: |
# Ensure Homebrew environment is available
eval $(brew shellenv)
# Use lockfile when present; avoid doing two full syncs (which can rebuild twice).
# Note: setup.py will automatically detect and configure Homebrew paths
if [ -f uv.lock ]; then
uv sync --extra test --frozen --verbose
else
uv sync --extra test --verbose
fi
- name: Run tests with coverage
run: |
uv run pytest test/python_tests -v \
--cov=mapnik \
--cov-report=term \
--cov-report=xml:coverage.xml \
--cov-report=html:htmlcov \
--junitxml=junit.xml
- name: Verify coverage files
if: always()
run: |
pwd
ls -la coverage.xml || echo "coverage.xml not found"
if [ -f coverage.xml ]; then
echo "✅ coverage.xml exists"
head -20 coverage.xml
else
echo "❌ coverage.xml not found"
exit 1
fi
- name: Upload coverage reports
uses: actions/upload-artifact@v4
if: always()
with:
name: coverage-reports-macos-${{ matrix.os }}-${{ matrix.arch_label }}
path: |
coverage.xml
htmlcov/
junit.xml
retention-days: 30
- name: Publish test results
uses: EnricoMi/publish-unit-test-result-action/macos@v2
if: always()
with:
files: junit.xml
check_name: Test Results (macOS ${{ matrix.os }} ${{ matrix.arch_label }})
comment_mode: off
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
if: always()
with:
files: coverage.xml
flags: unittests-macos-${{ matrix.os }}-${{ matrix.arch_label }}
name: python-mapnik-coverage-macos-${{ matrix.os }}-${{ matrix.arch_label }}
fail_ci_if_error: false
token: ${{ secrets.CODECOV_TOKEN }}
- name: Build sdist
run: |
uv build --sdist
- name: Upload sdist
uses: actions/upload-artifact@v4
with:
name: sdist-${{ matrix.os }}-${{ matrix.arch_label }}
path: dist/*.tar.gz
retention-days: 7