Skip to content
View geospatial-ci-cd's full-sized avatar

Block or report geospatial-ci-cd

Block user

Prevent this user from interacting with your repositories and sending you notifications. Learn more about blocking users.

You must be logged in to block users.

Maximum 250 characters. Please don’t include any personal information such as legal names or email addresses. Markdown is supported. This note will only be visible to you.
Report abuse

Contact GitHub support about this user’s behavior. Learn more about reporting abuse.

Report abuse
geospatial-ci-cd/README.md

Python Geospatial CI/CD & Wheel Building — GDAL · PROJ · PyProj

Python Geospatial CI/CD & Wheel Building

The practical reference for compiling, testing, and shipping Python geospatial C-extensions — the native code behind GDAL, PROJ, and PyProj — with modern CI/CD and wheel workflows.

🌍 Read it at geospatial-ci-cd.org →


What this is

Shipping a Python geospatial package means shipping compiled C and C++ to machines you will never see. Bindings for GDAL, PROJ, GEOS, and the raster and vector engines beneath them are not pure Python — they are platform-specific shared objects that must agree, byte for byte, with both the CPython interpreter that imports them and the native libraries they link against. When that agreement breaks, it breaks on a user's laptop or a production container as an ImportError or a segfault, not in your CI logs.

geospatial-ci-cd.org exists to make that native packaging reproducible instead of fragile. Every guide ships exact, copy-pasteable configuration and validation commands so you can move from a broken ImportError to a portable, audited wheel that imports identically on a laptop, a manylinux runner, and a serverless container.

Who it's for

Python GIS developers, package maintainers, DevOps and platform engineers, and data-platform teams who build or distribute anything that links GDAL, PROJ, GEOS, or their kin — pyproj, rasterio, shapely, fiona, or hand-rolled extensions.

What it covers

The material is organised around two areas, each broken into focused topics and step-by-step deep dives:

🧩 C-Extension Fundamentals & ABI Architecture

The binary contract itself — the rules that decide whether a compiled wheel imports at all:

  • The CPython Stable ABI (abi3) and version pinning that collapses your interpreter matrix
  • Vendoring PROJ and GDAL vs. relying on system libraries, and the wheel-size trade-offs
  • Shared-library path resolutionRPATH, RUNPATH, $ORIGIN, and the loader-precedence rules
  • Memory management — reference counting, GIL release around long transforms, and native-heap leaks
  • Cross-compilation — sysroots, toolchain files, and building aarch64 wheels without QEMU
  • Debugging import & linker failures, symbol visibility & namespace isolation, and platform-specific ABI quirks (macOS universal2, Windows DLL loading)
  • Security boundaries for compiling and running untrusted spatial input

🛠️ Build Tooling & Wheel Configuration

The pipeline that turns a manifest into a tagged, repaired, published artifact:

  • pyproject.toml, scikit-build-core, and CMake for spatial extensions
  • manylinux / musllinux base images and the glibc floor every Linux wheel inherits
  • Pixi / conda environment isolation and reproducible lockfiles
  • CI matrix recipes — GitHub Actions and GitLab CI, side by side
  • Testing & validationauditwheel show, clean-container smoke tests, functional checks
  • Publishing & distribution — trusted publishing to PyPI and wheel-size limits
  • Caching strategies that keep the build matrix affordable

Highlights

  • Copy-pasteable, not hand-wavy. Real pyproject.toml tables, CMake toolchain files, GitHub Actions and GitLab CI YAML, and the exact auditwheel / delocate / delvewheel commands.
  • Error-message driven. Failure modes quote the verbatim ImportError / OSError text so the fix matches what you actually paste into a search bar.
  • Hand-authored diagrams. Every guide carries an original, theme-aware SVG that explains the hardest idea on the page.
  • Fast, accessible, offline-friendly. A static site with a tight internal link graph, structured data, and a service worker.

Explore

Start here
🌍 Live site www.geospatial-ci-cd.org
🧩 C-Extension & ABI Fundamentals /geospatial-c-extension-fundamentals-abi-architecture/
🛠️ Build Tooling & Wheels /modern-python-build-tooling-wheel-configuration/

About this repository

This repository contains the source for the site — content in Markdown, rendered to a static site with Eleventy and deployed to Cloudflare.

npm install     # install dependencies
npm run serve   # local dev server with live reload
npm run build   # build the static site into _site/

License

Released under the MIT License.

Built for Python GIS developers, package maintainers, DevOps, and data-platform teams.

Popular repositories Loading

  1. geospatial-ci-cd geospatial-ci-cd Public

    Compiling, testing, and distributing Python geospatial C-extensions (GDAL/PROJ/PyProj) with modern CI/CD and wheel workflows — source for geospatial-ci-cd.org.

    JavaScript