pg_ripple — Release Procedure
This document describes how to release a new version of pg_ripple.
Versions follow the milestones in ROADMAP.md. Each release corresponds to a completed roadmap version (e.g. v0.1.0, v0.2.0).
Pre-Release Checklist
Complete every item before starting the release process.
-
All roadmap deliverables for the version are implemented
- Cross-check against the version's deliverables list in ROADMAP.md
- All deliverable checkboxes are ticked (
- [x]) in ROADMAP.md — if any are unticked, tick them now before proceeding
-
All exit criteria in ROADMAP.md are satisfied
- Verify each criterion explicitly — do not rely on partial evidence
-
Tests pass
cargo fmt --all -- --check(formatting)cargo clippy --features pg18 -- -D warnings(lint, zero warnings)cargo pgrx test pg18(unit + integration tests)cargo pgrx regress pg18 --postgresql-conf "allow_system_table_mods=on"(pg_regress suite, includesschema_statemigration schema check)bash tests/test_migration_chain.sh— verify all migration SQL scripts apply cleanly in sequence (requirescargo pgrx start pg18first; also run viajust test-migration)
-
Cargo.tomlversion field matches the release version- e.g.
version = "0.2.0"for a v0.2.0 release
- e.g.
-
pg_ripple.controldefault_versionmatches the release version -
Dependency versions are up to date
- Update
.versions.tomlifpg_trickleorpg_tideversions changed - Update the corresponding Dockerfile
ARG PG_TRICKLE_VERSION/ARG PG_TIDE_VERSIONto match src/lib.rsconstants are injected automatically at compile time from.versions.toml— no manual edits needed (DEP-VER-BUILD-01)- Run
bash scripts/check_dep_versions.shto verify Dockerfile alignment
- Update
-
Extension migration script created — CRITICAL
- File:
sql/pg_ripple--X.(Y-1).Z--X.Y.Z.sqlwhere the previous version is X.(Y-1).Z - If there are schema changes (ALTER TABLE, CREATE INDEX, etc.), include them in the script
- If there are no schema changes (new Rust functions), write only a comment header explaining what's new
- See Extension Versioning & Migration Scripts in AGENTS.md for the checklist and examples
- Without this file, users on earlier versions cannot upgrade via
ALTER EXTENSION ... UPDATE— they must dump/restore
- File:
-
CHANGELOG.md is up to date
- The
[Unreleased]section has been moved under the new version heading - Written in plain, accessible language (see Changelog Style below)
- All significant user-visible changes are included
- Date is set to today's date
- The
-
README.md is updated
- The "What works today (v0.X.Y)" section heading and body reflect the current release
- Describes only functionality implemented and merged in this version
- Remove planned features that haven't shipped yet
- The Roadmap table in the
## Roadmapsection is updated:- The newly released version row is bolded and its status cell is changed to
✅ Done - Any in-progress sentence above the table (e.g. "X is coming in a later milestone") no longer mentions capabilities that have now shipped
- The newly released version row is bolded and its status cell is changed to
- The "Where we're headed" section no longer lists the just-released version as upcoming — move it to a "What works today" bullet or remove it
-
No uncommitted changes —
git statusis clean -
Main branch is up to date —
git pull origin main
Release Checklist
Perform these steps in order.
-
Final test run
cargo fmt --all -- --check cargo clippy --features pg18 -- -D warnings cargo pgrx test pg18 cargo pgrx regress pg18 --postgresql-conf "allow_system_table_mods=on" bash tests/test_migration_chain.shAll five must pass with zero warnings and zero failures.
-
Documentation validation
Run the full docs check before tagging:
just docs-check mdbook build docsVerify:
just docs-check-linksexits 0 (no broken local links).just docs-check-summaryexits 0 (no orphan pages).just docs-check-http-routeslists no undocumented routes.just docs-check-guc-driftlists no missing GUCs with significant defaults.- New HTTP routes added in this version appear in
docs/src/reference/http-api.md. - New GUCs added in this version appear in
docs/src/reference/guc-reference.mdanddocs/gucs.md. - New public SQL functions appear in
docs/src/reference/sql-api.mdor are explicitly marked as internal/admin. - The migration script has upgrade docs if it changes user-visible schema.
CHANGELOG.mdlinks to any new user-facing docs pages.
-
Tag the release
Before tagging, verify the version bump and compatibility constant are correct:
# L16-13 (v0.117.0): verify version bump before tagging. just bump-version-dry # preview what would change just bump-version <new> <floor> # apply the bump (updates Cargo.toml, pg_ripple.control, # COMPATIBLE_EXTENSION_MIN in pg_ripple_http/src/main.rs) # Then inspect the changes: git diff --statUse an annotated tag with the version number:
git tag -a v0.X.Y -m "Release v0.X.Y — <version name from ROADMAP>" git push origin v0.X.YThis step is done manually. The release skill deliberately does not create tags.
-
The GitHub release is created automatically
Pushing the tag triggers
.github/workflows/release.yml, which:- Runs the full test + pg_regress suite on the tagged commit
- Extracts the changelog entry for this version from
CHANGELOG.md - Creates the GitHub release with the extracted notes
Monitor the workflow:
gh run list --limit 5 gh run view <run-id>
Post-Release Checklist
-
Verify the release workflow passed — check
.github/workflows/release.ymlrun on the taggh run list --limit 5
-
Verify the GitHub release page looks correct
gh release view v0.X.Y
-
Update the
[Unreleased]section in CHANGELOG.md- Add an empty
[Unreleased]section above the just-released version - Commit:
git commit -am "docs: start unreleased section after v0.X.Y"
- Add an empty
-
Announce the release (if applicable)
- Post to relevant channels, update project website, etc.
-
Verify the extension installs cleanly from the release
- On a fresh PostgreSQL 18 instance:
CREATE EXTENSION pg_ripple;
- On a fresh PostgreSQL 18 instance:
Changelog Style
The CHANGELOG.md should be written so that someone without deep knowledge of Rust, PostgreSQL internals, or RDF can understand what changed. Guidelines:
- Lead with what users can do, not how it was implemented
- Use short sentences and bullet points
- Avoid jargon — say "store and retrieve facts" instead of "triple CRUD via VP tables"
- Technical implementation details go in a separate "Technical Details" subsection for those who want them
- Each version section should open with a one-sentence summary
Version Numbering
| Range | Meaning |
|---|---|
| 0.x.y | Pre-1.0 development milestones — features may change |
| 1.0.0 | Production release — stable API, standards compliance |
| 1.x.y | Post-1.0 enhancements (federation, Cypher/GQL, etc.) |
Security Advisory Calendar
HTTP Companion Compatibility Window Policy (C16-01, v0.112.0)
The pg_ripple_http HTTP companion supports the prior 2 minor extension versions at any given
time. Concretely: if the current extension version is 0.X.Y, the companion built from the same
commit is guaranteed to work with extensions 0.(X-1).0 and 0.(X-2).0 (and any patch releases
within those minors). Older extension versions are served in degraded mode with a startup warning.
The COMPATIBLE_EXTENSION_MIN constant in pg_ripple_http/src/main.rs is updated atomically
with every just bump-version <new> <floor> invocation, and the release.yml CI gate
(compat-check job) enforces that this constant is never more than 1 minor version behind the
current extension. Set PG_RIPPLE_HTTP_STRICT_COMPAT=1 to convert the warning to a fatal error.
Security Advisory Calendar
RSA timing side-channel advisories (SEC-06, v0.92.0)
Two RUSTSEC advisories for the rsa crate are tracked in audit.toml:
RUSTSEC-2024-0436(Marvin attack on RSA decryption)RUSTSEC-2023-0071(PKCS#1 v1.5 timing side-channel)
Both expire 2026-12-01. Before v1.0.0:
- Run
cargo tree -i rsato verify thersacrate is still only a transitive dep. - If
reqwestis configured withrustls-tls-native-roots(no native-TLS), the RSA crate may not be reachable. If unreachable, remove the advisory ignores fromaudit.toml. - If still present as a transitive dep, renew the expiry dates in
audit.tomlafter confirming no pg_ripple code path exercises RSA decryption with untrusted input.
Action required before v1.0.0: Re-audit RSA advisory status and update
audit.toml.