There are two types of extension package structures in our codebase:
- Old structure (deprecated): Extensions like
supautils.nixthat directly define a single version in the nix expression for the package - New structure (current standard): Extensions that load multiple versions from
nix/ext/versions.json
Most extensions now use the new structure, which supports multiple versions via the versions.json file. The instructions below cover both approaches.
The new structure uses nix/ext/versions.json to manage multiple versions of extensions. Extensions that use this structure typically load their versions dynamically using code like:
allVersions = (builtins.fromJSON (builtins.readFile ./versions.json)).${pname};These extensions use stdenv.mkDerivation and require only basic fields in versions.json.
-
Create a branch off of
develop -
Update
nix/ext/versions.json- Add a new version entry for your extension:"extension_name": { "x.y.z": { "postgresql": ["15", "17"], "hash": "" } }
Fields:
"x.y.z": The version number (e.g.,"1.6.1")"postgresql": List of PostgreSQL major versions this extension supports (e.g.,["15", "17"])"hash": Initially set to""(we'll calculate this next)"rev"(optional): Some extensions use a specific git rev/tag (e.g.,"v1.6.4")"patches"(optional): Array of patch files if needed (e.g.,["pg_cron-1.3.1-pg15.patch"])
-
Calculate the hash - Run a nix build to get the correct hash:
nix build .#psql_15.exts.extension_name -LNix will fail and print the correct hash. Copy it and update the
hashfield inversions.json. -
Re-run the build to verify:
nix build .#psql_15.exts.extension_name -L -
Add any needed migrations into the
supabase/postgresmigrations directory -
Update
ansible/vars.ymlwith the new version as usual -
Run tests locally to verify the update succeeded:
nix flake check -L
This will:
- Build all extension versions
- Run all test suites
- Verify package integrity
- Check for any breaking changes
-
Ready for PR review
-
Once approved: If you want the change in a release, update
common-nix.vars.ymlwith the new version prior to merging
These extensions use mkPgrxExtension and require additional Rust and pgrx version information.
-
Create a branch off of
develop -
Update
nix/ext/versions.json- Add a new version entry with Rust/pgrx fields:"extension_name": { "x.y.z": { "postgresql": ["15", "17"], "hash": "", "pgrx": "0.12.6", "rust": "1.81.0" } }
Fields:
"x.y.z": The version number"postgresql": List of PostgreSQL major versions supported"hash": Initially set to""(calculate in next step)"pgrx": pgrx version (check the extension's Cargo.toml or use the current standard version)"rust": Rust toolchain version (check the extension's requirements or use current standard)
-
Calculate the hash:
nix build .#psql_15.exts.extension_name -LNix build will fail and print the correct hash. Update the
hashfield inversions.json.If needed, you can access the extension name by running the command
nix flake show -
Update
previouslyPackagedVersionsin the extension'sdefault.nixfile:For pgrx extensions, you need to add the previous version to the
previouslyPackagedVersionslist. For example, innix/ext/wrappers/default.nix:previouslyPackagedVersions = [ "0.5.3" # ← Add the old version here when adding 0.5.4 "0.5.2" # ... other versions ];
This ensures that migration paths are created for users upgrading from older versions.
-
Re-run the build to verify:
nix build .#psql_15.exts.extension_name -L -
Add any needed migrations into the
supabase/postgresmigrations directory -
Update
ansible/vars.ymlwith the new version -
Run full test suite:
nix flake check -L
For pgrx extensions, this will also verify that migration paths work correctly.
-
Ready for PR review
-
Once approved: Update
common-nix.vars.ymlif releasing
Need to update pgrx or Rust versions? See Updating cargo-pgrx Extensions for the complete guide covering pgrx version updates, Rust toolchain updates (including
nix flake update rust-overlay), and troubleshooting.
Note: This structure is being phased out. New extensions should use the versions.json approach above.
For extensions like supautils.nix that haven't been migrated to the new structure yet:
-
Create a branch off of
develop -
Update the version directly in the
.nixfile:version = "3.0.0"; # Update this
-
Temporarily clear the hash:
hash = ""; # Clear this temporarily
Save the file and stage it:
git add . -
Calculate the hash:
nix build .#psql_15.exts.supautils -LNix will print the calculated sha256 value.
-
Update the hash with the calculated value:
hash = "sha256-EKKjNZQf7HwP/MxpHoPtbEtwXk+wO241GoXVcXpDMFs=";
-
Re-run the build:
nix build .#psql_15.exts.supautils -L -
Add migrations as needed
-
Update
ansible/vars.yml -
Run tests:
nix flake check -L
-
PR review and merge (update
common-nix.vars.ymlif releasing)
The nix flake check -L command is your primary local testing tool:
-L: Shows full build logs (useful for debugging failures)- What it checks:
- All extension builds for all supported PostgreSQL versions
- Extension test suites
- Package structure integrity
- Migration path validity (for multi-version extensions)
- Integration tests
Tip: Run this locally before creating a PR to catch issues early.
Hash mismatch errors: Make sure you're building with an empty hash first (hash = "";), then copy the exact hash from the error output.
Build failures: Check that:
- PostgreSQL versions in
versions.jsonare correct - For pgrx extensions: Rust and pgrx versions are compatible
- All required dependencies are listed
Test failures: Run with -L flag to see detailed logs:
nix flake check -L 2>&1 | tee build.log