Skip to content

feat(cargo-pgrx): build RPM package#2324

Open
daamien wants to merge 4 commits into
pgcentralfoundation:developfrom
daamien:rpm
Open

feat(cargo-pgrx): build RPM package#2324
daamien wants to merge 4 commits into
pgcentralfoundation:developfrom
daamien:rpm

Conversation

@daamien

@daamien daamien commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Hi !

Distributing RPM packages of an PGRX extension is still a clumsy process. I personnally use nfpm which is great but it seems like cargo-pgrx should be able to build basic packages on its own.

This is a draft proposal to add RPM generation to the cargo pgrx package command.

Based on the Cargo.toml content: if a package.metadata.rpm section is present then a RPM is built in the target directory.

Basic example :

$ cargo new world

$ # Add a `package.metadata.rpm` section in the manifest

$ head Cargo.toml
[package]
name = "world"
version = "0.0.0"
edition = "2021"
homepage = "https://hello.world"
description = "Hello World"
license = "MIT"

[package.metadata.rpm]
vendor = "ACME Corp."

$ cargo pgrx package
       Using PgConfig("pg18") and `pg_config` from /usr/bin/pg_config
    Building extension with features pg18
     Running command "cargo" "--config" "target.'cfg(all(target_family = \"unix\", not(target_os = \"macos\")))'.rustflags = [\"-C\", \"link-arg=-Wl,--no-gc-sections\"]" "build" "--lib" "--release" "--features" "pg18" "--no-default-features" "--message-format=json-render-diagnostics"
    Finished [`release` profile [optimized]](https://doc.rust-lang.org/cargo/reference/profiles.html#default-profiles) target(s) in 0.18s
  Installing extension
     Copying control file to target/release/world-pg18/usr/share/postgresql/extension/world.control
     Copying shared library to target/release/world-pg18/usr/lib/postgresql/world.so
  Discovered 1 SQL entities: 0 schemas (0 unique), 1 functions, 0 types, 0 enums, 0 sqls, 0 ords, 0 hashes, 0 aggregates, 0 triggers
     Writing SQL entities to /home/damien/dev/github/daamien/pgrx/world/target/release/world-pg18/usr/share/postgresql/extension/world--0.0.0.sql
    Finished installing world
     Writing RPM package in "/home/damien/dev/github/daamien/pgrx/world/target/release/world-pg18"

$ ls /home/damien/dev/github/daamien/pgrx/world/target/release/world-pg18
Permissions Size User   Date Modified Name
drwxr-xr-x     - damien  7 Jun 23:41   usr
.rw-r--r--  197k damien 15 Jun 21:15   world-pg18-0.0.0-1.x86_64.rpm

$ rpm --query --info /home/damien/dev/github/daamien/pgrx/world/target/release/world-pg18/world-pg18-0.0.0-1.x86_64.rpm
Name        : world-pg18
Version     : 0.0.0
Release     : 1
Architecture: x86_64
Install Date: (not installed)
Group       : Unspecified
Size        : 434079
License     : MIT
Signature   : (none)
Source RPM  : (none)
Build Date  : Sun 13 Sep 2020 02:26:40 PM CEST
Build Host  : (none)
Vendor      : ACME Corp.
URL         : https://hello.world
Summary     : Hello World
Description :
Hello World

$ rpm --query --list /home/damien/dev/github/daamien/pgrx/world/target/release/world-pg18/world-pg18-0.0.0-1.x86_64.rpm
/usr/pgsql-18/lib/world.so
/usr/pgsql-18/share/extension
/usr/pgsql-18/share/extension/world--0.0.0.sql
/usr/pgsql-18/share/extension/world.control

The PR is still rough because I'd like some feedback before going any further :

  • Is cargo pgrx package the right command to add this ? Or should I add cargo pgrx rpm ?

  • is it ok to rely on the [package.metadata.rpm] ?

  • For a first implement, i'd say that RPM signing is not necessary.

  • Generally the idea is to produce a very simple package and if some developers have more advanced use cases let me come forward and ask for more features

@eeeebbbbrrrr

Copy link
Copy Markdown
Contributor

I haven't studied the code changes but I'm okay with the spirit of this. I agree this is a gap in cargo pgrx package.

Can we add .deb too?

@daamien

daamien commented Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

I haven't studied the code changes but I'm okay with the spirit of this. I agree this is a gap in cargo pgrx package.

Thanks, I'll clean up the code, add tests and documentation

Can we add .deb too?

Sure. In a separate MR or in this one ?

@eeeebbbbrrrr

Copy link
Copy Markdown
Contributor

Sure. In a separate MR or in this one ?

Lets do it here, if you don't mind.

@daamien

daamien commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

Lets do it here, if you don't mind.

Right

Turns out that cargo-deb crate is a different beast and does not expose its internal function so I might end up writing a temporary Manifest and call out a cargo deb command like this :

cargo deb --no-build --manifest-path <tmp_manifest> --output <dir>

I see there's already some let mut command = Command::new(cargo); calls in some places so I guess it's ok to add new ones ?

@eeeebbbbrrrr

Copy link
Copy Markdown
Contributor

I guess it's ok to add new ones ?

That's a runtime dependency that someone would need to install via cargo install, yeah?

That's not the end of the world if it otherwise gets us to making this stuff easy.

@daamien

daamien commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

I guess it's ok to add new ones ?

That's a runtime dependency that someone would need to install via cargo install, yeah?

Yes that would be completely optionnal and only required if the extension developper adds a [package.metadata.deb] section in her/his Cargo.toml file.

That's not the end of the world if it otherwise gets us to making this stuff easy.

@eeeebbbbrrrr

Copy link
Copy Markdown
Contributor

Yes that would be completely optionnal and only required if the extension developper adds a [package.metadata.deb] section in her/his Cargo.toml file.

We'll just need to document it well, but I think that's totally fine. I am imagining a new "packaging.md" section in our little mdbook will be wanted anyways.

This is a draft proposal to add RPM generation to the `cargo pgrx
package` command.

Based on the Cargo.toml content: if a `package.metadata.rpm` section
is present then a RPM is built in the target directory.
@daamien

daamien commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

Hey !

Unfortunately the Command::new(cargo) approach was a dead end. So I went back and forth exploring other ideas.

I ended up using the arx-pack crate which is very new but does both the DEB and RPM packaging in an elegant way.

https://crates.io/crates/arx-pack

We could also add APK and Arch Linux packaging very easily...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants