Skip to content

Development

Project Setup

This project uses uv as its build system and package manager.

# Install everything (dev + all extras + bench)
uv sync --all-groups --all-extras

Running Tests

Tests require a running PostgreSQL instance with the PGMQ extension.

Automated (Docker)

make test

This command: 1. Tears down any existing pgmq-postgres and pgmq-plain-postgres containers. 2. Starts a fresh PGMQ-enabled Postgres container on port 5432. 3. Starts a plain Postgres container (no PGMQ extension) on port 5433 for SQL install tests. 4. Waits for them to be ready. 5. Runs the full test suite, including SQL install tests against plain Postgres on port 5433.

Manual

If you already have PGMQ installed:

make test-env

Override connection parameters with environment variables:

export PG_HOST=localhost
export PG_PORT=5432
export PG_USERNAME=postgres
export PG_PASSWORD=postgres
export PG_DATABASE=postgres

SQL-only install tests

Run SQL install tests against plain Postgres (defaults to localhost:5433):

make run-plain-postgres
sleep 10
make install-pgmq-sql
make test-sql-install-env

make install-pgmq-sql and make test-sql-install-env both target plain Postgres via PG_SQL_INSTALL_* variables (see SQL Installation).

CI also runs this path in .github/workflows/sql_install_tests.yml.

Fetch pinned pgmq.sql from a PGMQ extension release

src/pgmq/sql/pgmq.sql is not committed. The repo pins a PGMQ extension semver tag in src/pgmq/sql/VERSION. CI and make build download pgmq-extension/sql/pgmq.sql from that tag, then uv build packs it. uv build alone does not fetch the file.

# Download the pinned release (skips when the file matches VERSION)
make vendor-pgmq-sql

# Vendor, build, and fail if the wheel is missing pgmq.sql
make build

# Download a specific extension tag without changing the pin
make vendor-pgmq-sql TAG=v1.13.0

uv run python -m unittest tests.test_install.TestEmbeddedInstallSql -v

To change the pin locally:

uv run python scripts/vendor_pgmq_sql.py v1.13.0 --update-pin --force

Automated pin notices (dual trigger)

.github/workflows/vendor_pgmq_sql.yml watches the VERSION pin using two complementary triggers:

Trigger When Upstream change required?
Daily cron (06:00 UTC) Polls pgmq/pgmq latest release No
repository_dispatch Immediate on extension release Optional

The pgmq org does not allow GITHUB_TOKEN to create pull requests. When the pin is behind a release, the workflow opens a dependencies issue. Maintainers update src/pgmq/sql/VERSION and open the pull request. If the extension dispatch fails or is not configured, the daily job picks up the new release on the next run. If both fire for the same version, the workflow reuses the open issue (no duplicate issue).

Optional fast path — add to pgmq/pgmq release.yml after a release is published:

- name: Trigger pgmq-py SQL vendor update
  uses: peter-evans/repository-dispatch@v3
  with:
    token: ${{ secrets.PGMQ_PY_DISPATCH_TOKEN }}
    repository: pgmq/pgmq-py
    event-type: pgmq-extension-release
    client-payload: '{"tag":"${{ github.ref_name }}"}'

Create PGMQ_PY_DISPATCH_TOKEN in the extension repo: a PAT with permission to dispatch workflows on pgmq/pgmq-py.

Manual run:

gh workflow run vendor_pgmq_sql.yml --repo pgmq/pgmq-py -f tag=v1.13.0

Verify dispatch without upstream changes:

gh api repos/pgmq/pgmq-py/dispatches \
  -f event_type=pgmq-extension-release \
  -f client_payload='{"tag":"v1.13.0"}'

Docker Helpers

# Start a local PGMQ-enabled Postgres
make run-pgmq-postgres

# Start plain Postgres for SQL-only install tests
make run-plain-postgres

# Tear them down
make clear-postgres
make clear-plain-postgres

Lint and Format

# Auto-fix and format
make format

# Check only
make lint

These wrap ruff — the only linter/formatter used in this project.

Writing Tests

  • Sync + psycopg tests go in tests/test_integration.py.
  • Async + asyncpg tests go in tests/test_async_integration.py.
  • SQLAlchemy sync tests go in tests/test_sqlalchemy_integration.py.
  • SQLAlchemy async tests go in tests/test_sqlalchemy_async_integration.py.
  • Pure Python unit tests (no DB) go in tests/test_sql_conversion.py.

Tests that depend on bleeding-edge PGMQ features must gracefully skip when UndefinedFunction or RaiseException is raised, because CI images may lag behind the extension.

Building Documentation

This documentation is designed for MkDocs with the Material theme.

Install MkDocs

pip install mkdocs mkdocs-material mike

Serve Locally

mkdocs serve

Build

mkdocs build

Versioned Deployment (Mike)

This project uses mike to deploy versioned documentation.

# Deploy the current version
mike deploy 1.1.0 latest

# Set the default version
mike set-default latest

mike stores versions as separate commits on the gh-pages branch and generates a version switcher in the UI.

Contributing Guidelines

  • Follow the existing code style (ruff enforces this).
  • Add docstrings to all public methods.
  • Use log_with_context instead of bare print() in library code.
  • Keep SQL centralized in src/pgmq/_sql.py.
  • Update pyproject.toml version when releasing.
  • Add tests for new features.