Test and Release pgrx Extensions with pgxn-tools
Yesterday I released v1.6.0 of the pgxn/pgxn-tools Docker image with a new
command: pgrx-build-test
works much like the existing pg-build-test
utility for PGXS extensions, but for pgrx extensions. Here’s an example
from pg-jsonschema-boon, a pgrx extension I’ve been working on:
name: ๐งช Test
on:
push:
jobs:
test:
runs-on: ubuntu-latest
container: pgxn/pgxn-tools
strategy:
matrix:
pg: [11, 12, 13, 14, 15, 16]
name: ๐ Postgres ${{ matrix.pg }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Start PostgreSQL ${{ matrix.pg }}
run: pg-start ${{ matrix.pg }}
- name: Setup Rust Cache
uses: Swatinem/rust-cache@v2
- name: Test on PostgreSQL ${{ matrix.pg }}
run: pgrx-build-test
The format is the same as for pg-build-test
, starting with installing a
specific version of Postgres from the Postgres Apt repository (supporting
versions 8.2 โ 17). It then adds the Swatinem/rust-cache action to speed up
Rust builds by caching dependencies, and then simply calls pgrx-build-test
instead of pg-build-test
. Here’s what it does:
- Extracts the pgrx version from the
Cargo.toml
file and installs it (requires v0.11.4 or higher) - Initializes pgrx to use the Postgres installed by
pg-start
- Builds the extension with
cargo pgrx package
- Tests the extension with
cargo pgrx test
- Installs the extension with
cargo pgrx install
- Checks for a
Makefile
withinstallcheck
configured and, if it exists, runsmake installcheck
This last step allows one to include PGXS-style pg_regress
tests in
addition to Rust/pgrx tests, as pg-jsonschema-boon does. Here’s a successful
run.
Special thanks to Eric Ridge and @Jubilee for all the help and improvements in pgrx v0.11.4 that enable this to work transparently.
pgrx Release Pattern
The pattern for releasing a prgx extension on PGXN is the same as before,
although you may want to generate the META.json
file from a template. For
example, the pg-jsonschema-boon Makefile creates META.json
from
META.json.in
by reading the version from Cargo.toml
and replacing
@CARGO_VERSION@
, like so:
DISTVERSION = $(shell perl -nE '/^version\s*=\s*"([^"]+)/ && do { say $$1; exit }' Cargo.toml)
META.json: META.json.in Cargo.toml
@sed "s/@CARGO_VERSION@/$(DISTVERSION)/g" $< > $@
The release workflow uses it like so:
name: ๐ Release on PGXN
on:
push:
# Release on semantic version tag.
tags: ['v[0-9]+.[0-9]+.[0-9]+']
jobs:
release:
name: ๐ Release on PGXN
runs-on: ubuntu-latest
container: pgxn/pgxn-tools
env:
PGXN_USERNAME: ${{ secrets.PGXN_USERNAME }}
PGXN_PASSWORD: ${{ secrets.PGXN_PASSWORD }}
steps:
- name: Check out the repo
uses: actions/checkout@v4
- name: Bundle the Release
env: { GIT_BUNDLE_OPTS: --add-file META.json }
run: make META.json && pgxn-bundle
- name: Release on PGXN
run: pgxn-release
Note the “Bundle the Release” step, which first calls make META.json
to
generate the dated file, and tells pgxn-bundle
to add the META.json
via the GIT_BUNDLE_OPTS
environment variable. The project also excludes
the META.json.in
file from the bundle in its .gitattributes
file,
and excludes META.json
from the project repository in its .gigignore
file.
Looking forward to seeing all your pgrx projects on PGXN!