PLAN_PACKAGING.md — Distribution Packaging

Status: INFRA-2 implemented (META.json with release_status: testing) Target version: v1.0.0 (flip to stable + upload .deb/.rpm) Author: pg_trickle project

Implemented in v0.7.0: META.json at the project root with release_status: "testing" and version 0.7.0. At v1.0.0 update the version and flip release_status to "stable", then run pgxn upload.


1. Overview

Three packaging targets for v1.0.0:

Target Audience Priority
PGXN PostgreSQL community / developers High
Debian/Ubuntu .deb Linux sysadmins, PGDG apt users High
RPM / RHEL Enterprise Linux users, PGDG yum users Medium

All packages target PostgreSQL 18 on x86_64 and aarch64.


2. Prerequisites

# Cargo.toml — fields required by all packaging targets
[package]
name    = "pg_trickle"
version = "1.0.0"
edition = "2021"
license = "Apache-2.0"
description = "PostgreSQL streaming tables with incremental view maintenance"
repository  = "https://github.com/geir/pg-trickle"

Required tools:

cargo install cargo-pgrx    # pgrx build tooling
cargo install cargo-deb     # .deb builder

3. PGXN Packaging

3.1 META.json

{
  "name": "pg_trickle",
  "abstract": "Streaming tables with incremental view maintenance for PostgreSQL 18",
  "version": "1.0.0",
  "maintainer": "pg_trickle contributors",
  "license": "apache_2_0",
  "provides": {
    "pg_trickle": {
      "abstract": "Streaming tables with IVM",
      "file": "pg_trickle.control",
      "docfile": "README.md",
      "version": "1.0.0"
    }
  },
  "prereqs": {
    "runtime": {
      "requires": { "PostgreSQL": "18.0.0" }
    }
  },
  "tags": ["ivm", "streaming", "materialized view", "cdc", "rust"],
  "release_status": "stable"
}

3.2 Build workflow

# Build the release artifact
cargo pgrx package --pg-config $(pg_config)

# Verify the package structure
ls target/release/pg_trickle-pg18/

# Upload to PGXN (requires PGXN account + API key)
pgxn upload pg_trickle-1.0.0.zip

3.3 CI job (.github/workflows/pgxn.yml)

on:
  push:
    tags: ['v*']
jobs:
  pgxn:
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v4
      - uses: pgxn/setup-pgxn@v1
        with: { pg-version: '18' }
      - run: cargo pgrx package --pg-config $(pg_config)
      - run: pgxn upload pg_trickle-${GITHUB_REF_NAME#v}.zip
        env:
          PGXN_USERNAME: ${{ secrets.PGXN_USERNAME }}
          PGXN_PASSWORD: ${{ secrets.PGXN_PASSWORD }}

4. Debian / Ubuntu .deb

4.1 Cargo.deb configuration in Cargo.toml

[package.metadata.deb]
name            = "postgresql-18-pg-trickle"
section         = "database"
priority        = "optional"
depends         = "postgresql-18"
maintainer-scripts = "debian/"
assets = [
  ["target/release/pg_trickle.so",   "usr/lib/postgresql/18/lib/", "755"],
  ["pg_trickle.control",             "usr/share/postgresql/18/extension/", "644"],
  ["pg_trickle--*.sql",              "usr/share/postgresql/18/extension/", "644"],
]

4.2 Build

# Cross-compile for amd64 & arm64
cargo deb --target x86_64-unknown-linux-gnu
cargo deb --target aarch64-unknown-linux-gnu

# Test install on clean PG18 system
dpkg -i target/x86_64-unknown-linux-gnu/debian/postgresql-18-pg-trickle_1.0.0_amd64.deb
psql -c "CREATE EXTENSION pg_trickle;"

4.3 PPA Hosting

  • Short term: GitHub Releases artifact
  • Medium term: self-hosted apt repo via aptly + GitHub Pages
  • Long term: PGDG community apt repository (requires PGDG maintainer sponsorship)

5. RPM / RHEL

5.1 Spec file outline (pg_trickle.spec)

Name:       pg_trickle_18
Version:    1.0.0
Release:    1%{?dist}
Summary:    PostgreSQL 18 streaming tables with IVM
License:    Apache-2.0
Requires:   postgresql18

%install
install -d %{buildroot}%{_libdir}/pgsql/
install -m 755 target/release/pg_trickle.so %{buildroot}%{_libdir}/pgsql/
install -d %{buildroot}%{_datadir}/pgsql/extension/
install -m 644 pg_trickle.control %{buildroot}%{_datadir}/pgsql/extension/
install -m 644 pg_trickle--*.sql  %{buildroot}%{_datadir}/pgsql/extension/

5.2 Build

rpmbuild -ba pg_trickle.spec

Distribution: GitHub Releases initially; PGDG yum repository if community interest warrants it.


6. Testing Packages

Each package MUST be tested on a clean environment before release:

# Debian
docker run --rm -it ubuntu:24.04 bash -c "
  apt-get install -y postgresql-18 ./postgresql-18-pg-trickle_1.0.0_amd64.deb &&
  pg_ctlcluster 18 main start &&
  psql -U postgres -c 'CREATE EXTENSION pg_trickle; SELECT pgtrickle.version();'
"

# RPM
docker run --rm -it rockylinux:9 bash -c "
  dnf install -y postgresql18-server pg_trickle_18-1.0.0-1.el9.x86_64.rpm &&
  postgresql-setup --initdb && systemctl start postgresql &&
  psql -U postgres -c 'CREATE EXTENSION pg_trickle; SELECT pgtrickle.version();'
"

7. GitHub Actions Cost Note

See PLAN_GITHUB_ACTIONS_COST.md for runner cost analysis. Packaging jobs should only run on release tags (v*) to minimise spend.


References