Contributing to pgmq-cpp

July 26, 2026 ยท View on GitHub

Thank you for helping improve pgmq-cpp. This is an independent community project and is not an official PGMQ support channel.

Suspected vulnerabilities must be reported privately as described in SECURITY.md, not through a public issue or pull request.

Before opening a change

For correctness bugs, include:

  • PostgreSQL and PGMQ versions;
  • operating system, compiler, CMake version, and build preset;
  • the smallest reproducer;
  • expected and actual delivery/transaction behavior;
  • whether the test used a real PostgreSQL/PGMQ instance;
  • SQLSTATE and pgmq::Error::operation() where available.

Do not include credentials or production connection strings. Reliability claims based only on mocks are not sufficient for queue, transaction, lease, disconnect, or crash behavior.

Development setup

Requirements:

  • C++20 compiler;
  • CMake 3.25+;
  • Ninja for the supplied Linux presets;
  • libpq and nlohmann/json (the included vcpkg manifest is supported);
  • Docker with Compose for the isolated integration database when running the real-database suite;
  • optional Doxygen and clang-tidy.

Configure and build on Linux:

export VCPKG_ROOT=/path/to/vcpkg
cmake --preset linux-debug
cmake --build --preset linux-debug
ctest --test-dir build/linux-debug --output-on-failure

Run the sanitizer configuration:

cmake --preset linux-sanitize
cmake --build --preset linux-sanitize
ctest --preset linux-sanitize

On Windows:

$env:VCPKG_ROOT = 'C:\path\to\vcpkg'
cmake --preset windows-debug
cmake --build --preset windows-debug
ctest --preset windows-debug

The project windows-debug, windows-release, and linux-debug presets explicitly set PGMQ_CPP_REGISTER_DOCKER_TESTS=ON. A direct configure defaults that option to OFF, and linux-sanitize also keeps it off. Override it explicitly when choosing whether the real Docker fixture should be registered.

Consult tests/ and the verification ledger for the current integration database command and test labels. Never point destructive tests at a shared, private, staging, or production database.

Design rules

  • Keep the public API C++20-only and free of libpq types.
  • Use RAII for connections, results, and transactions.
  • Do not share one libpq connection concurrently between threads.
  • Bind SQL values. A dynamic identifier is allowed only after QueueName validation and PostgreSQL identifier quoting.
  • Use std::chrono for durations and time points.
  • Preserve pgmq::Error category, SQLSTATE, operation, and detail.
  • Do not introduce an alternative error model beside exceptions.
  • Do not auto-commit a caller-owned pgmq::Transaction.
  • Keep WorkerTransaction handlers free of transaction-control SQL and SQL that acknowledges or changes their current task; execute() is a trusted escape hatch, not a sandbox.
  • Keep queues bounded and stop-aware; no unbounded thread or task creation.
  • Preserve the read_ct ownership guard for all regular-mode renewals and terminal actions.
  • Keep notifications advisory and polling authoritative.
  • Never claim exactly-once behavior for arbitrary external effects.
  • Do not add a web service, broker daemon, authentication layer, or workflow engine to this library.

Substantial design changes need an ADR under docs/adr/.

Tests required by change type

ChangeMinimum evidence
Value validation, parsing, backoffFocused unit test
SQL function or result parsingUnit test plus real PGMQ integration test
Pooling, worker scheduling, stop behaviorDeterministic unit/concurrency test
Lease, retry, dead-letter, transactionReal PGMQ integration test
Disconnect or reconnectControlled local database interruption test
Crash boundarySeparate process terminated at a deterministic sync point
Installed CMake interfaceFresh external consumer configure/build
Performance claimRaw benchmark output and full environment metadata

Tests must have bounded timeouts and clean up only their uniquely named queues and project-owned containers/processes.

Documentation and API compatibility

Public additions require:

  • API comments or Doxygen-visible declarations;
  • a realistic usage example;
  • compatibility-table updates when an upstream SQL capability is involved;
  • reliability/failure-model updates when semantics change;
  • a changelog entry.

Code snippets in README and docs/ must compile against the public headers. QueueWorkerConfig is constructed with a QueueName; it is not a designated aggregate.

Pull request checklist

  • The change is scoped and has no unrelated formatting churn.
  • Unit tests pass.
  • Required real-database tests pass, or are clearly marked not run.
  • Sanitizers/static analysis were run where relevant, or marked not run.
  • Install-consumer verification passes for public package changes.
  • Documentation and changelog are updated.
  • No secrets, generated build trees, benchmark marketing claims, or upstream PGMQ source snapshots are committed accidentally.
  • External-side-effect semantics remain described as at-least-once.

By contributing, you agree that your contribution is licensed under the project's MIT License.