Skip to content

Generalize focal PostGIS build to a PG12-16 pipeline - #1214

Merged
Volkan Cetin (vlkncetin) merged 2 commits into
developfrom
postgis-focal
Aug 21, 2026
Merged

Volkan Cetin (vlkncetin) merged 2 commits into
developfrom
postgis-focal

Conversation

@vlkncetin

Copy link
Copy Markdown
Contributor

Why

PGDG removed Ubuntu 20.04 entirely — focal-pgdg 404s on its Release file, and the frozen apt-archive mirror tops out at PostGIS 3.5.3. There is no 3.6.x focal build to pin to, so a newer PostGIS on focal has to be rebuilt from upstream source.

Driver is MSRC Incident-31000000674353, which requires PostGIS 3.6.4.

What this adds

File Purpose
dockerfiles/focal-postgis-builder/Dockerfile focal builder image, PGDG archive for build tooling
scripts/build_postgis_focal upstream tarball + frozen focal debian/ → dpkg-buildpackage
scripts/smoke_test_focal_postgis_debs installs the set in a clean focal container and proves the extension works
.github/workflows/build-postgis-focal.yml build → sign → verify → smoke test

Modelled closely on build-pg-focal.yml / build_pg_focal / smoke_test_focal_debs, including the debsigner mount convention and the .ddeb→.deb rename.

How it differs from the PostgreSQL core pipeline

No per-major matrix, and no assemble job. PostGIS's Debian packaging is multi-version by design (debian/pgversions + pg_buildext), so one source build emits postgresql-<major>-postgis-3 for every major in a single pass. The shared postgis / postgis-doc packages are produced exactly once, so there is no duplicate-name problem to de-duplicate.

The archive components list includes 12. focal-pg-builder enables main 13 14 15 16 17; PostGIS 3.6 supports PG12+, so postgresql-server-dev-12 has to be reachable.

PG11 is unsupported. PostGIS 3.6 requires PostgreSQL 12–18.

Two deliberate deviations from PGDG's package layout

Both are load-bearing — each fixes a failure that is silent at the package layer.

1. The arch-independent -scripts package is folded into the runtime package.
Upstream splits it so the SQL can be shared across architectures; we build amd64 only, so there is no benefit. Worse, the runtime's dependency on -scripts is unversioned, so a partial update happily pairs a 3.6.4 .so with 3.5.3 SQL and CREATE EXTENSION then runs the wrong definitions. One package makes that impossible.

2. Extension control files are named postgis-3.6.control, not postgis-3.control, registered with update-alternatives at priority 36 (PGDG uses 30).
PGDG's -scripts prerm runs update-alternatives --remove ... postgis-3.control on removal. Sharing that path means removing the old package drops the last alternative and deletes the postgis.control symlink — leaving a host where dpkg -l reports the new version, default_version reads 3.6.4, the right contrib directory is on disk, and yet:

ERROR:  extension "postgis" is not available
DETAIL:  Could not open extension control file ".../postgis.control": No such file or directory

A distinct suffix keeps the two alternatives independent. The runtime also carries Conflicts/Replaces/Provides on postgresql-<major>-postgis-3-scripts so apt removes the old package in the same transaction.

Integrity

The upstream tarball is sha256-pinned and verified (download.osgeo.org publishes no detached signature):

POSTGIS_SHA256=ed8dc6679f1e06f7b113592b04cde2a7e00f1b1e681294c8ca2204058990cec6

The frozen debian/ packaging is fetched with apt-get source, so it is authenticated by the archive's signed Release.

Testing

Built and verified locally under rootless podman using these exact scripts.

Build:

[2/7] postgis-3.6.4.tar.gz: OK              ← sha256 verified
[5/7] Package: postgis / postgis-doc / postgresql-PGVERSION-postgis-3
==> Verify runtime <-> dbgsym pairing   PG12–PG16 OK
==> DONE. 10 packages at 3.6.4-1.citus20.04+1

Smoke test — clean install, and install over PGDG's 3.5.3 runtime + dbgsym + scripts:

[3/6] Scenario A: clean install
    PG12–PG16 OK   ext=3.6.4 lib=3.6.4 alternatives->postgis-3.6.control
[4/6] Scenario B: upgrade over PGDG PostGIS 3.5.3
[5/6] PG12–PG16 OK   ext=3.6.4 lib=3.6.4 area=12308778361
SMOKE TEST PASSED

The build also fails hard if a dbgsym's exact-version dependency ever drifts from its runtime — that mismatch previously broke downstream image burns and is invisible until apt --fix-broken install runs.

Notes for reviewers

  • RUN_TESTS=1 (upstream regression suite) is wired but never exercised — it may need build-deps the image lacks. Worth one dispatch before relying on it.
  • DEB_REVISION defaults to 1.citus20.04+1 → 3.6.4-1.citus20.04+1, which sorts above 3.5.3+dfsg-1~exp1.pgdg20.04+1. Happy to change if that's not the convention you want.
  • The push: trigger on postgis-focal mirrors pg-focal in the PG workflow, so this can be run before it reaches develop.
  • Unrelated observation: dockerfiles/debsigner/scripts/import_and_sign has no post-signing verification, unlike rpmsigner, which was explicitly hardened against the "silent unsigned" bug. gpg failing there can exit 0 with unsigned debs. This workflow's Verify signatures are embedded step covers it for this pipeline, but the signer itself may deserve the same treatment in a separate PR.

@vlkncetin

Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree company="Microsoft"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, LGTM!

@vlkncetin
Volkan Cetin (vlkncetin) merged commit 4a52326 into develop Aug 21, 2026
86 checks passed
@vlkncetin
Volkan Cetin (vlkncetin) deleted the postgis-focal branch August 21, 2026 12:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants