Skip to content

Commit 0d8fdb3

Browse files
committed
ci: build wheel
1 parent e613828 commit 0d8fdb3

3 files changed

Lines changed: 156 additions & 60 deletions

File tree

.github/workflows/release.yml

Lines changed: 116 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
name: Release
22

33
on:
4+
pull_request:
5+
branches: [ main, master, develop ]
46
push:
57
tags:
68
- 'v*.*.*'
@@ -30,7 +32,6 @@ jobs:
3032
echo "version_number=${VERSION#v}" >> $GITHUB_OUTPUT
3133
3234
build-wheels:
33-
needs: [extract-version]
3435
strategy:
3536
fail-fast: false
3637
matrix:
@@ -52,7 +53,119 @@ jobs:
5253
- name: Build wheels
5354
env:
5455
CIBW_BUILD_VERBOSITY: 1
56+
# Avoid local build.py shadowing the "build" module used by PEP 517 frontend.
57+
CIBW_BUILD_FRONTEND: "pip"
5558
CIBW_BEFORE_BUILD: "pip install uv && uv sync --frozen --no-dev || uv sync --no-dev"
59+
# Ensure pkg-config can find libmapnik.pc across manylinux/apt paths.
60+
CIBW_ENVIRONMENT_LINUX: >-
61+
PKG_CONFIG_PATH=/usr/lib64/pkgconfig:/usr/lib/pkgconfig:/usr/local/lib/pkgconfig:/usr/local/lib64/pkgconfig:/opt/lib/pkgconfig:$PKG_CONFIG_PATH
62+
# Linux: install system dependencies in manylinux container
63+
CIBW_BEFORE_ALL_LINUX: |
64+
set -euo pipefail
65+
if command -v apt-get >/dev/null 2>&1; then
66+
mkdir -p /etc/apt/sources.list.d /etc/apt/preferences.d
67+
echo "deb http://deb.debian.org/debian sid main" >> /etc/apt/sources.list.d/sid.list
68+
echo 'Package: *
69+
Pin: release a=sid
70+
Pin-Priority: 100' > /etc/apt/preferences.d/sid
71+
apt-get update
72+
apt-get install -y build-essential pkg-config libbz2-dev
73+
apt-get install -y -t sid libmapnik-dev fonts-noto-cjk
74+
elif command -v dnf >/dev/null 2>&1 || command -v yum >/dev/null 2>&1; then
75+
DNF_BIN=$(command -v dnf || command -v yum)
76+
if command -v dnf >/dev/null 2>&1; then
77+
dnf install -y dnf-plugins-core
78+
# Enable repo variants across EL8/EL9.
79+
dnf config-manager --set-enabled powertools || true
80+
dnf config-manager --set-enabled crb || true
81+
else
82+
yum install -y yum-utils || true
83+
fi
84+
$DNF_BIN install -y epel-release || true
85+
$DNF_BIN install -y \
86+
bzip2-devel \
87+
gcc gcc-c++ make \
88+
pkgconfig
89+
if ! $DNF_BIN install -y mapnik-devel; then
90+
echo "mapnik-devel not available in enabled repos; building Mapnik from source." >&2
91+
$DNF_BIN repolist || true
92+
$DNF_BIN list available "mapnik*" || true
93+
$DNF_BIN install -y \
94+
boost-devel \
95+
freetype-devel \
96+
libpng-devel \
97+
libjpeg-turbo-devel \
98+
libtiff-devel \
99+
libicu-devel \
100+
zlib-devel \
101+
libxml2-devel \
102+
proj-devel \
103+
gdal-devel \
104+
harfbuzz-devel \
105+
cairo-devel \
106+
libcurl-devel \
107+
sqlite-devel \
108+
git \
109+
curl \
110+
wget \
111+
tar
112+
PYBIN=$(ls -d /opt/python/cp312-cp312/bin/python /opt/python/cp3*/bin/python | head -1)
113+
"$PYBIN" -m pip install --upgrade pip
114+
"$PYBIN" -m pip install scons
115+
# Build a newer Boost (>=1.83) since EL8 provides 1.66.
116+
BOOST_VER=1.83.0
117+
BOOST_VER_UNDERSCORE=1_83_0
118+
rm -rf /tmp/boost-src
119+
mkdir -p /tmp/boost-src
120+
cd /tmp/boost-src
121+
BOOST_TARBALL="boost-${BOOST_VER}.tar.gz"
122+
curl -L -o "$BOOST_TARBALL" "https://github.com/boostorg/boost/releases/download/boost-${BOOST_VER}/boost-${BOOST_VER}.tar.gz"
123+
tar -xzf "$BOOST_TARBALL"
124+
cd "boost_${BOOST_VER_UNDERSCORE}"
125+
./bootstrap.sh --prefix=/usr/local --with-libraries=regex,program_options,system,filesystem,thread
126+
./b2 -j"$(nproc)" link=shared runtime-link=shared install
127+
rm -rf /tmp/mapnik-src
128+
git clone --depth 1 --branch v4.2.0 https://github.com/mapnik/mapnik.git /tmp/mapnik-src
129+
cd /tmp/mapnik-src
130+
SCBIN="$(dirname "$PYBIN")/scons"
131+
"$SCBIN" configure PREFIX=/usr/local BOOST_INCLUDES=/usr/local/include BOOST_LIBS=/usr/local/lib
132+
"$SCBIN" -j"$(nproc)"
133+
"$SCBIN" install
134+
cd /
135+
fi
136+
# Fonts are optional for building; try common package names.
137+
$DNF_BIN install -y google-noto-sans-cjk-ttc-fonts || \
138+
$DNF_BIN install -y google-noto-cjk-fonts || \
139+
$DNF_BIN install -y noto-sans-cjk-fonts || true
140+
else
141+
echo "No supported package manager found (apt-get or dnf/yum)." >&2
142+
exit 1
143+
fi
144+
echo "libmapnik.pc locations (if any):"
145+
find /usr /opt /usr/local -name "libmapnik.pc" -print 2>/dev/null || true
146+
# macOS: install dependencies via Homebrew
147+
CIBW_BEFORE_ALL_MACOS: "brew install mapnik icu4c pkg-config boost gdal proj harfbuzz libx11 xorgproto libxext libxrender libxau libxdmcp xtrans"
148+
# macOS: set up build environment
149+
CIBW_BEFORE_BUILD_MACOS: |
150+
eval $(brew shellenv)
151+
HOMEBREW_PREFIX=$(brew --prefix)
152+
ICU4C_PREFIX=$(brew --prefix icu4c)
153+
BOOST_PREFIX=$(brew --prefix boost)
154+
GDAL_PREFIX=$(brew --prefix gdal)
155+
PROJ_PREFIX=$(brew --prefix proj)
156+
HARFBUZZ_PREFIX=$(brew --prefix harfbuzz)
157+
XORGPROTO_PREFIX=$(brew --prefix xorgproto)
158+
LIBX11_PREFIX=$(brew --prefix libx11)
159+
LIBXEXT_PREFIX=$(brew --prefix libxext)
160+
LIBXRENDER_PREFIX=$(brew --prefix libxrender)
161+
LIBXAU_PREFIX=$(brew --prefix libxau)
162+
LIBXDMCP_PREFIX=$(brew --prefix libxdmcp)
163+
XTRANS_PREFIX=$(brew --prefix xtrans)
164+
XORGPROTO_PKGCONFIG_DIR=$(find "$HOMEBREW_PREFIX/Cellar/xorgproto" -type d -name "pkgconfig" 2>/dev/null | head -1)
165+
[ -z "$XORGPROTO_PKGCONFIG_DIR" ] && XORGPROTO_PKGCONFIG_DIR="$XORGPROTO_PREFIX/share/pkgconfig"
166+
export PKG_CONFIG_PATH="$HOMEBREW_PREFIX/lib/pkgconfig:$HOMEBREW_PREFIX/share/pkgconfig:$ICU4C_PREFIX/lib/pkgconfig:$GDAL_PREFIX/lib/pkgconfig:$PROJ_PREFIX/lib/pkgconfig:$HARFBUZZ_PREFIX/lib/pkgconfig:$LIBX11_PREFIX/lib/pkgconfig:$LIBXEXT_PREFIX/lib/pkgconfig:$LIBXRENDER_PREFIX/lib/pkgconfig:$LIBXAU_PREFIX/lib/pkgconfig:$LIBXDMCP_PREFIX/lib/pkgconfig:$XTRANS_PREFIX/share/pkgconfig:$XORGPROTO_PKGCONFIG_DIR:$XORGPROTO_PREFIX/share/pkgconfig:$XORGPROTO_PREFIX/lib/pkgconfig:$PKG_CONFIG_PATH"
167+
export CXXFLAGS="-I$BOOST_PREFIX/include -I$GDAL_PREFIX/include -I$PROJ_PREFIX/include -I$HARFBUZZ_PREFIX/include $CXXFLAGS"
168+
export LDFLAGS="-L$BOOST_PREFIX/lib -L$GDAL_PREFIX/lib -L$PROJ_PREFIX/lib -L$HARFBUZZ_PREFIX/lib $LDFLAGS"
56169
run: |
57170
cibuildwheel --output-dir wheelhouse
58171
@@ -63,40 +176,14 @@ jobs:
63176
path: wheelhouse/*.whl
64177
retention-days: 7
65178

66-
build-sdist:
67-
needs: [extract-version]
68-
runs-on: ubuntu-latest
69-
permissions:
70-
contents: write
71-
steps:
72-
- name: Checkout code
73-
uses: actions/checkout@v6
74-
with:
75-
submodules: recursive
76-
77-
- name: Install uv
78-
uses: astral-sh/setup-uv@v7
79-
80-
- name: Build sdist
81-
run: |
82-
uv build --sdist
83-
84-
- name: Upload sdist
85-
uses: actions/upload-artifact@v4
86-
with:
87-
name: sdist
88-
path: dist/*.tar.gz
89-
retention-days: 7
90-
91179
release:
92180
needs:
93181
- extract-version
94182
- build-wheels
95-
- build-sdist
96183
runs-on: ubuntu-latest
97184
permissions:
98185
contents: write
99-
if: github.event_name == 'push'
186+
if: (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) || github.event_name == 'workflow_dispatch'
100187

101188
steps:
102189
- name: Download all artifacts
@@ -117,6 +204,7 @@ jobs:
117204
- name: Create GitHub Release
118205
uses: softprops/action-gh-release@v2
119206
with:
207+
token: ${{ secrets.GITHUB_TOKEN }}
120208
tag_name: ${{ needs.extract-version.outputs.version }}
121209
name: Release ${{ needs.extract-version.outputs.version }}
122210
body: |
@@ -152,8 +240,6 @@ jobs:
152240
dist/*.tar.gz
153241
draft: false
154242
prerelease: false
155-
env:
156-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
157243

158244
- name: Summary
159245
run: |

.github/workflows/test.yml

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ jobs:
6868
# Ensure /etc/os-release exists (required by some actions' OS detection).
6969
apt-get install -y base-files
7070
apt-get install -y build-essential pkg-config libbz2-dev
71-
apt-get install -y -t sid libmapnik-dev fonts-noto-cjk
71+
apt-get install -y -t sid libmapnik-dev
7272
7373
- name: Install uv
7474
uses: astral-sh/setup-uv@v7
@@ -123,6 +123,17 @@ jobs:
123123
name: python-mapnik-coverage-linux-${{ matrix.arch_label }}
124124
fail_ci_if_error: false
125125
token: ${{ secrets.CODECOV_TOKEN }}
126+
127+
- name: Build sdist
128+
run: |
129+
uv build --sdist
130+
131+
- name: Upload sdist
132+
uses: actions/upload-artifact@v4
133+
with:
134+
name: sdist-${{ matrix.os }}-${{ matrix.arch_label }}
135+
path: dist/*.tar.gz
136+
retention-days: 7
126137

127138
test-macos:
128139
strategy:
@@ -176,7 +187,7 @@ jobs:
176187
- name: Install and cache Homebrew tools
177188
uses: tecolicom/actions-use-homebrew-tools@v1
178189
with:
179-
tools: mapnik icu4c pkg-config boost gdal proj harfbuzz libx11 xorgproto libxext libxrender libxau libxdmcp
190+
tools: mapnik icu4c pkg-config boost gdal proj harfbuzz libx11 xorgproto libxext libxrender libxau libxdmcp xtrans
180191
key: mapnik-${{ matrix.os }}-${{ matrix.arch_label }}-20260118
181192

182193
- name: Setup pkg-config and build environment
@@ -192,6 +203,12 @@ jobs:
192203
PROJ_PREFIX=$(brew --prefix proj)
193204
HARFBUZZ_PREFIX=$(brew --prefix harfbuzz)
194205
XORGPROTO_PREFIX=$(brew --prefix xorgproto)
206+
LIBX11_PREFIX=$(brew --prefix libx11)
207+
LIBXEXT_PREFIX=$(brew --prefix libxext)
208+
LIBXRENDER_PREFIX=$(brew --prefix libxrender)
209+
LIBXAU_PREFIX=$(brew --prefix libxau)
210+
LIBXDMCP_PREFIX=$(brew --prefix libxdmcp)
211+
XTRANS_PREFIX=$(brew --prefix xtrans)
195212
# Find the actual xorgproto pkg-config directory (may be in Cellar with version)
196213
XORGPROTO_PKGCONFIG_DIR=$(find "$HOMEBREW_PREFIX/Cellar/xorgproto" -type d -name "pkgconfig" 2>/dev/null | head -1)
197214
if [ -z "$XORGPROTO_PKGCONFIG_DIR" ]; then
@@ -210,14 +227,20 @@ jobs:
210227
echo "PROJ_PREFIX=$PROJ_PREFIX" >> $GITHUB_ENV
211228
echo "HARFBUZZ_PREFIX=$HARFBUZZ_PREFIX" >> $GITHUB_ENV
212229
echo "XORGPROTO_PREFIX=$XORGPROTO_PREFIX" >> $GITHUB_ENV
230+
echo "LIBX11_PREFIX=$LIBX11_PREFIX" >> $GITHUB_ENV
231+
echo "LIBXEXT_PREFIX=$LIBXEXT_PREFIX" >> $GITHUB_ENV
232+
echo "LIBXRENDER_PREFIX=$LIBXRENDER_PREFIX" >> $GITHUB_ENV
233+
echo "LIBXAU_PREFIX=$LIBXAU_PREFIX" >> $GITHUB_ENV
234+
echo "LIBXDMCP_PREFIX=$LIBXDMCP_PREFIX" >> $GITHUB_ENV
235+
echo "XTRANS_PREFIX=$XTRANS_PREFIX" >> $GITHUB_ENV
213236
echo "XORGPROTO_PKGCONFIG_DIR=$XORGPROTO_PKGCONFIG_DIR" >> $GITHUB_ENV
214237
echo "Homebrew prefix: $HOMEBREW_PREFIX"
215238
echo "Mapnik prefix: $MAPNIK_PREFIX"
216239
echo "xorgproto pkg-config dir: $XORGPROTO_PKGCONFIG_DIR"
217240
# Set PKG_CONFIG_PATH to include Homebrew's pkg-config directories
218241
# This ensures pkg-config can find Mapnik and its dependencies (ICU, Boost, GDAL, PROJ, HarfBuzz, X11 proto, etc.)
219242
# Note: xorgproto .pc files are in Cellar/xorgproto/<version>/share/pkgconfig
220-
echo "PKG_CONFIG_PATH=$HOMEBREW_PREFIX/lib/pkgconfig:$HOMEBREW_PREFIX/share/pkgconfig:$ICU4C_PREFIX/lib/pkgconfig:$GDAL_PREFIX/lib/pkgconfig:$PROJ_PREFIX/lib/pkgconfig:$HARFBUZZ_PREFIX/lib/pkgconfig:$XORGPROTO_PKGCONFIG_DIR:$XORGPROTO_PREFIX/share/pkgconfig:$PKG_CONFIG_PATH" >> $GITHUB_ENV
243+
echo "PKG_CONFIG_PATH=$HOMEBREW_PREFIX/lib/pkgconfig:$HOMEBREW_PREFIX/share/pkgconfig:$ICU4C_PREFIX/lib/pkgconfig:$GDAL_PREFIX/lib/pkgconfig:$PROJ_PREFIX/lib/pkgconfig:$HARFBUZZ_PREFIX/lib/pkgconfig:$LIBX11_PREFIX/lib/pkgconfig:$LIBXEXT_PREFIX/lib/pkgconfig:$LIBXRENDER_PREFIX/lib/pkgconfig:$LIBXAU_PREFIX/lib/pkgconfig:$LIBXDMCP_PREFIX/lib/pkgconfig:$XTRANS_PREFIX/share/pkgconfig:$XORGPROTO_PKGCONFIG_DIR:$XORGPROTO_PREFIX/share/pkgconfig:$XORGPROTO_PREFIX/lib/pkgconfig:$PKG_CONFIG_PATH" >> $GITHUB_ENV
221244
# Set CXXFLAGS and LDFLAGS to include Boost, GDAL, PROJ, and HarfBuzz headers and libraries
222245
echo "CXXFLAGS=-I$BOOST_PREFIX/include -I$GDAL_PREFIX/include -I$PROJ_PREFIX/include -I$HARFBUZZ_PREFIX/include $CXXFLAGS" >> $GITHUB_ENV
223246
echo "LDFLAGS=-L$BOOST_PREFIX/lib -L$GDAL_PREFIX/lib -L$PROJ_PREFIX/lib -L$HARFBUZZ_PREFIX/lib $LDFLAGS" >> $GITHUB_ENV
@@ -292,4 +315,15 @@ jobs:
292315
flags: unittests-macos-${{ matrix.os }}-${{ matrix.arch_label }}
293316
name: python-mapnik-coverage-macos-${{ matrix.os }}-${{ matrix.arch_label }}
294317
fail_ci_if_error: false
295-
token: ${{ secrets.CODECOV_TOKEN }}
318+
token: ${{ secrets.CODECOV_TOKEN }}
319+
320+
- name: Build sdist
321+
run: |
322+
uv build --sdist
323+
324+
- name: Upload sdist
325+
uses: actions/upload-artifact@v4
326+
with:
327+
name: sdist-${{ matrix.os }}-${{ matrix.arch_label }}
328+
path: dist/*.tar.gz
329+
retention-days: 7

pyproject.toml

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -57,34 +57,10 @@ test-extras = ["test"]
5757
# Linux build configuration
5858
[tool.cibuildwheel.linux]
5959
# Use manylinux_2_28 (Debian 12 / Bookworm based)
60-
manylinux-x86_64-image = "manylinux_2_28_x86_64"
61-
manylinux-aarch64-image = "manylinux_2_28_aarch64"
62-
63-
# Install system dependencies before build
64-
before-all = """
65-
# Add Debian sid repository for Mapnik 4.2
66-
echo "deb http://deb.debian.org/debian sid main" >> /etc/apt/sources.list.d/sid.list
67-
echo 'Package: *\nPin: release a=sid\nPin-Priority: 100' > /etc/apt/preferences.d/sid
68-
69-
# Install build dependencies
70-
apt-get update
71-
apt-get install -y build-essential pkg-config libbz2-dev
72-
apt-get install -y -t sid libmapnik-dev fonts-noto-cjk
73-
"""
60+
manylinux-x86_64-image = "quay.io/pypa/manylinux_2_28_x86_64"
61+
manylinux-aarch64-image = "quay.io/pypa/manylinux_2_28_aarch64"
7462

7563
# macOS build configuration
7664
[tool.cibuildwheel.macos]
7765
# Build for both x86_64 and arm64
7866
archs = ["x86_64", "arm64"]
79-
80-
# Install dependencies via Homebrew (run once before all builds)
81-
before-all = "brew install mapnik icu4c pkg-config boost gdal proj harfbuzz"
82-
83-
# Set environment variables for each build
84-
# These are exported in the build environment
85-
before-build = """
86-
eval $(brew shellenv)
87-
export PKG_CONFIG_PATH=$(brew --prefix)/lib/pkgconfig:$(brew --prefix)/opt/icu4c/lib/pkgconfig:$(brew --prefix)/opt/boost/lib/pkgconfig:$(brew --prefix)/opt/gdal/lib/pkgconfig:$(brew --prefix)/opt/proj/lib/pkgconfig:$(brew --prefix)/opt/harfbuzz/lib/pkgconfig:$PKG_CONFIG_PATH
88-
export CXXFLAGS="-I$(brew --prefix)/opt/boost/include -I$(brew --prefix)/opt/gdal/include -I$(brew --prefix)/opt/proj/include -I$(brew --prefix)/opt/harfbuzz/include $CXXFLAGS"
89-
export LDFLAGS="-L$(brew --prefix)/opt/boost/lib -L$(brew --prefix)/opt/gdal/lib -L$(brew --prefix)/opt/proj/lib -L$(brew --prefix)/opt/harfbuzz/lib $LDFLAGS"
90-
"""

0 commit comments

Comments
 (0)