Skip to content

Add native RPM/DEB packaging and release pipeline for ColdFront#44

Open
maqeel75 wants to merge 15 commits into
mainfrom
native-packages
Open

Add native RPM/DEB packaging and release pipeline for ColdFront#44
maqeel75 wants to merge 15 commits into
mainfrom
native-packages

Conversation

@maqeel75

@maqeel75 maqeel75 commented Jul 8, 2026

Copy link
Copy Markdown
Member

Summary

Adds native RPM/DEB packaging and a full release pipeline for ColdFront, replacing the
previous GoReleaser-only release workflow. A single tag push now builds, signs, and publishes
packages for all ColdFront components across the supported EL and Debian/Ubuntu platforms.

Components

Package Type Scope
pgedge-coldfront Go binaries (archiver, partitioner, compactor) PG-independent, per-arch
pgedge-postgresql-<N>-coldfront ColdFront PostgreSQL extension per PG major (16/17/18)
pgedge-pg-duckdb_<N> / pgedge-postgresql-<N>-pg-duckdb pg_duckdb 1.5.4 (pinned commit) per PG major
pgedge-coldfront-duckdb-extensions Patched iceberg/avro/azure/postgres_scanner .duckdb_extension PG-independent, per-arch
pgedge-lakekeeper Lakekeeper (Apache Iceberg REST Catalog) prebuilt binary + systemd service PG-independent, per-arch

Target matrix

  • RPM: almalinux:9, almalinux:10
  • DEB: ubuntu jammy, noble, resolute; debian bookworm, trixie
  • Arches: amd64 + arm64 (native arm64 runners, no QEMU)

Debian bullseye is intentionally excluded (EOL, and the prebuilt lakekeeper binary requires glibc >= 2.34).

Release pipeline (.github/workflows/release.yml)

  • Repo-type routing via pgedge-parse-release-tag, detect matrix via pgedge-detect-build-matrix,
    merged into one combined per-(component, PG major, distro, arch) matrix.
  • The DuckDB extensions are built once per arch on manylinux_2_28 (glibc 2.28 baseline → portable),
    verified by a load-test gate that LOADs all four extensions in the real DuckDB engine on every
    supported distro, then repackaged per distro without recompiling.
  • Signed SBOMs (per-format keys), RPM signing, push to dnf.pgedge.com / apt.pgedge.com, S3 backup, and an
    aggregated promotion manifest + Slack notification.
  • Target distros are centralized in env.RPM_IMAGES / env.DEB_IMAGES (single source of truth, consumed
    by every detect step and the load-test gate).

Configuration / runtime notes

  • lakekeeper: ships /etc/lakekeeper/lakekeeper.env (a %config/conffile, so edits survive upgrades)
    and a systemd unit that is not enabled or started automatically. Requires an external PostgreSQL
    15+ database; the admin sets LAKEKEEPER__PG_DATABASE_URL_WRITE + LAKEKEEPER__PG_ENCRYPTION_KEY and
    runs the one-time lakekeeper migrate before starting. No hard PostgreSQL package dependency (it is a
    network service). Port configurable via LAKEKEEPER__LISTEN_PORT (default 8181).
  • duckdb-extensions: installed to /usr/lib/pgedge/coldfront/duckdb-extensions/v<ver>/linux_<arch>/;
    a shipped config sample documents pointing pg_duckdb at them via duckdb.extension_directory
    (plus allow_unsigned_extensions = true and autoinstall_known_extensions = false).

Testing

  • pg_duckdb, coldfront extension, coldfront binaries, lakekeeper, and duckdb-extensions build-tested in
    containers (el9 / bullseye→now noble / trixie as applicable), including signed RPMs validated with
    rpm --checksig and signed SBOMs embedded in both formats.
  • End-to-end tag run exercised the full matrix; lakekeeper DEB pre-release version handling fixed (the
    release download URL now uses the clean upstream version, not the ~-decorated package version).

Follow-ups

  • ubuntu:resolute requires a matching resolute suite on apt.pgedge.com and in the apt-repo-builder
    reprepro config for the DEB push to land.

@maqeel75
maqeel75 requested a review from vyruss as a code owner July 8, 2026 15:28
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1f6ad580-dfa2-41bd-857f-521674e6d824

📥 Commits

Reviewing files that changed from the base of the PR and between 6a007ab and 6e92d2c.

📒 Files selected for processing (1)
  • .github/workflows/release.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/release.yml

📝 Walkthrough

Walkthrough

This PR adds a compactor binary, shared build helpers, packaging assets for five components, and a tag-routed release workflow that builds, verifies, packages, publishes, backs up, and reports release artifacts.

Changes

Packaging and Release Pipeline

Layer / File(s) Summary
Compactor binary build via GoReleaser
.goreleaser.yaml
Adds the compactor build target and includes it in the coldfront archive with archiver and partitioner.
Shared build and signing helper scripts
common/build.sh, common/common-functions.sh
Adds the common build entrypoint plus helpers for syft installation, build-environment setup, repository configuration, OS detection, GPG key import, RPM signing, and signature validation.
ColdFront CLI binaries packaging
packaging/coldfront-bin/*
Adds RPM and Debian packaging for archiver, partitioner, and compactor, including configuration and signed SBOM artifacts.
ColdFront PostgreSQL extension packaging
packaging/coldfront/*
Adds RPM and Debian PGXS packaging for the ColdFront PostgreSQL extension across PostgreSQL major versions.
ColdFront DuckDB extensions build and packaging
packaging/coldfront-duckdb-extensions/*
Adds build-once compilation and RPM/Debian repackaging for four patched DuckDB extensions, with configuration and signed SBOM artifacts.
pg_duckdb extension packaging
packaging/pg_duckdb/*
Adds pinned-source RPM and Debian packaging for pg_duckdb, including PostgreSQL version substitution and curl build handling.
Lakekeeper packaging
packaging/lakekeeper/*
Adds prebuilt binary packaging, systemd service and environment templates, documentation, user/group setup, and signed SBOM artifacts.
Release workflow orchestration
.github/workflows/release.yml
Adds tag routing, matrix detection, DuckDB extension verification, package publication, repository backups, and manifest aggregation.

Estimated code review effort: 4 (Complex) | ~75 minutes

Suggested reviewers: dpage

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: native RPM/DEB packaging and a release pipeline for ColdFront.
Description check ✅ Passed The description is directly related to the changeset and accurately outlines the packaging and release pipeline updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch native-packages

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Checkov (3.3.8)
.github/workflows/release.yml

Traceback (most recent call last):
File "/usr/local/bin/checkov", line 2, in
from checkov.main import Checkov
ModuleNotFoundError: No module named 'checkov'


Comment @coderabbitai help to get the list of available commands.

@codacy-production

codacy-production Bot commented Jul 8, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

# Conflicts:
#	.github/workflows/release.yml

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🧹 Nitpick comments (7)
packaging/coldfront-bin/rpm/coldfront.spec (1)

5-5: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Drop the redundant BuildArch: %{_arch}

rpmbuild already targets the native arch here, so this line is unnecessary. Removing it keeps the spec cleaner and avoids the extra spec re-parse caveat if macros are added above it later.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packaging/coldfront-bin/rpm/coldfront.spec` at line 5, Remove the redundant
BuildArch declaration from the spec so the package relies on rpmbuild’s native
architecture handling. Update the top-level RPM spec definition near the
existing debug_package macro, keeping the rest of the package metadata unchanged
and ensuring no other macros depend on the removed BuildArch line.
.github/workflows/release.yml (1)

123-126: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Set persist-credentials: false on checkouts.

None of the actions/checkout steps disable credential persistence, so the default GITHUB_TOKEN is written into .git/config. The workflow subsequently clones private repos using an explicit PGEDGE_BUILDER_TOKEN and uploads workspace artifacts, so the persisted default credential isn't needed and is best dropped as defense-in-depth. This applies to every actions/checkout step in the file (also flagged at lines 190, 318, 363, 427, 525, 625, 688, 752, 833).

🔒 Example
             - name: Checkout
               uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
               with:
                   fetch-depth: 0
+                  persist-credentials: false
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 123 - 126, The Checkout steps in
this workflow are persisting the default GITHUB_TOKEN in .git/config, which is
unnecessary since the workflow uses explicit credentials elsewhere. Update every
actions/checkout usage in the release workflow to set persist-credentials to
false, keeping the existing fetch-depth and other settings intact. Use the
Checkout step entries as the targets for this change across the file.

Source: Linters/SAST tools

packaging/coldfront-duckdb-extensions/build-deb.sh (1)

80-81: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low value

Predictable /tmp path (static analysis hint).

/tmp/pg_deb_build is a fixed, predictable path; a local attacker on a shared runner could pre-create/symlink it. Low real risk on isolated ephemeral CI runners, but mktemp -d would be more robust.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packaging/coldfront-duckdb-extensions/build-deb.sh` around lines 80 - 81, The
build script uses a predictable fixed /tmp path for the deb build directory,
which should be replaced with an unpredictable temporary directory. Update the
build flow around rename_ddeb_packages in build-deb.sh to create the workspace
with mktemp -d (or equivalent), store it in a variable, and pass that variable
instead of hardcoding /tmp/pg_deb_build so the temporary location is unique per
run.

Source: Linters/SAST tools

packaging/lakekeeper/build-rpm.sh (1)

26-34: 🔒 Security & Privacy | 🔵 Trivial | ⚖️ Poor tradeoff

No integrity verification of downloaded upstream binary before signing/shipping.

The Lakekeeper release tarball, LICENSE, and NOTICE are fetched with wget and used directly (no checksum or signature check) before the resulting package is GPG-signed and published. If the upstream release asset were ever corrupted in transit or the wrong artifact served, it would be repackaged and signed as trusted pgEdge output without detection. GitHub now publishes SHA256 digests for release assets, and Lakekeeper's release notes may include checksums — verifying against these before packaging would close this gap.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packaging/lakekeeper/build-rpm.sh` around lines 26 - 34, The download flow in
build-rpm.sh fetches the Lakekeeper tarball, LICENSE, and NOTICE with wget and
packages them without verifying integrity. Update the packaging step around the
tarball download and the LICENSE/NOTICE fetches to validate the artifacts
against an expected SHA256 digest or release-published checksum before they are
copied into rpmbuild/SOURCES and signed; use the existing build-rpm.sh download
logic and the tarball/REPO_RAW variables to keep the verification tied to the
fetched release version.
packaging/coldfront-duckdb-extensions/build-extensions.sh (1)

41-46: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Redundant submodule + unbounded vcpkg clone.

git submodule update --init --recursive --depth 1 (line 41) fully clones the duckdb submodule inside duckdb-iceberg, which is then immediately discarded and re-cloned pinned at v${DUCKDB_VERSION} (lines 43-44) — wasted bandwidth/time on every build. Separately, git clone "${VCPKG_REPO}" (line 45) clones the full vcpkg history/ports tree with no --depth 1, which is a large repo and slows every CI run unnecessarily.

Consider excluding the duckdb path from the submodule update (or deinit it before line 41) and shallow-cloning vcpkg.

♻️ Suggested tweak
-git -C "$ICE" submodule update --init --recursive --depth 1 --jobs 8
+git -C "$ICE" submodule update --init --recursive --depth 1 --jobs 8 -- $(git -C "$ICE" config --file .gitmodules --get-regexp path | awk '{print $2}' | grep -v '^duckdb$')
...
-git clone "${VCPKG_REPO}" "${BUILD_ROOT}/vcpkg"
+git clone --depth 1 "${VCPKG_REPO}" "${BUILD_ROOT}/vcpkg"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packaging/coldfront-duckdb-extensions/build-extensions.sh` around lines 41 -
46, The build script is doing extra work by fully updating the nested duckdb
submodule only to delete and re-clone it later, and it is also cloning vcpkg
without a shallow fetch. Update build-extensions.sh so the initial git submodule
update for the ICE checkout excludes or deinitializes the duckdb path before the
clone replacement, and change the vcpkg clone to a shallow checkout. Keep the
fix localized around the submodule handling and the vcpkg clone steps in the
build flow.
packaging/coldfront-duckdb-extensions/deb/debian/rules (1)

22-29: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

SBOM+GPG signing block duplicated across every packaging script.

This exact syft/gpg sequence is repeated near-verbatim in packaging/pg_duckdb/deb/debian/rules, packaging/lakekeeper/deb/debian/rules, and the RPM %build sections. Consider extracting a shared helper (e.g. a common/sign-sbom.sh sourced/called with $SNAME and output dir) to avoid drift when the signing logic needs to change (e.g. key selection strategy).

♻️ Sketch of a shared helper
# common/sign-sbom.sh
sign_sbom() {
  local sname="$1" outdir="$2"
  mkdir -p "$outdir"
  syft dir:"${3:-$PWD}" -o cyclonedx-json > "$outdir/${sname}-sbom.json" || exit 1
  local key_id
  key_id=$(gpg --list-secret-keys --with-colons | awk -F: '/^sec/{print $5}' | head -n 1)
  gpg --armor --detach-sign --local-user "$key_id" \
    --output "$outdir/${sname}-sbom.json.asc" "$outdir/${sname}-sbom.json" || exit 1
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packaging/coldfront-duckdb-extensions/deb/debian/rules` around lines 22 - 29,
The SBOM generation and GPG signing logic in this debian/rules fragment is
duplicated across multiple packaging scripts, so move the syft/gpg sequence into
a shared helper and call it from execute_before_dh_install. Add a reusable
helper such as common/sign-sbom.sh that accepts the package name and output
directory (and optionally the source dir), then update the packaging entry
points like execute_before_dh_install and the other debian/rules/RPM build
sections to invoke that helper instead of inlining the signing steps. Keep the
helper responsible for key selection, SBOM output naming, and signature file
creation so future signing changes happen in one place.
packaging/pg_duckdb/build-rpm.sh (1)

34-36: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Verify curl tarball integrity before use.

The curl source is fetched over HTTPS but never checksummed/verified against a known-good hash or signature before being staged into SOURCES and built. Given this build exists specifically to remediate a curl CVE, pinning a hash guards against a compromised/mirrored download.

🔒 Proposed fix: verify SHA256 checksum
   echo "Staging curl ${CURL_VERSION} source (build-time, EL9 only)..."
   wget -q "https://curl.se/download/curl-${CURL_VERSION}.tar.gz" \
     -O ~/rpmbuild/SOURCES/curl-${CURL_VERSION}.tar.gz
+  wget -q "https://curl.se/download/curl-${CURL_VERSION}.tar.gz.sha256" -O /tmp/curl.sha256
+  (cd ~/rpmbuild/SOURCES && sha256sum -c <(sed "s|curl-${CURL_VERSION}.tar.gz|curl-${CURL_VERSION}.tar.gz|" /tmp/curl.sha256))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packaging/pg_duckdb/build-rpm.sh` around lines 34 - 36, The curl staging step
in build-rpm.sh downloads the tarball in the build flow without verifying its
integrity, so add a SHA256 (or similar) verification immediately after the wget
in the curl staging block. Use the existing CURL_VERSION-specific download path
and update the build logic to compare the fetched tarball against a known-good
pinned digest before placing it into ~/rpmbuild/SOURCES, so the check is tied to
the curl download step rather than the later RPM build.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@common/common-functions.sh`:
- Around line 167-168: The key selection in sign_rpms is ambiguous because it
re-derives KEY_ID from gpg --list-secret-keys and head -n 1, which can pick the
wrong secret key on a populated keyring. Update import_gpg_keys to capture the
imported key’s fingerprint/key ID at import time, then pass or export that value
explicitly into sign_rpms so it uses the intended key instead of listing the
keyring again. Keep the fix centered around import_gpg_keys and sign_rpms so the
signing step is tied to the specific imported key.
- Around line 108-113: The GPG key file path variables are mislabeled: PRI_FILE
points to public.key and PUB_FILE points to private.key, which is confusing for
future edits. Rename the variables in the key-loading block of the shell script
to match their actual contents, and update the corresponding cat and rm -f uses
so the public/private key handling is immediately clear. Keep the existing
behavior intact while aligning the variable names with the files they reference.
- Around line 3-11: The install_syft function still executes a remote installer
directly with curl piped into sudo sh, which leaves the build host exposed to
unverified code. Update install_syft to first download the syft install script
to a local temporary file, verify its integrity or authenticity before use, and
only then run it with sudo; keep the existing SYFT_VERSION pinning and reuse the
install_syft symbol so the fix is localized.
- Around line 61-79: The repo setup helpers are installing packages from
unverified remote locations and `configure_pgedge_apt_repo` uses a predictable
`/tmp/pgedge-release.deb` path. Update `configure_pgedge_apt_repo` to download
into a unique temporary file created with `mktemp` and ensure it is cleaned up
after `sudo dpkg -i`; also review `configure_pgedge_dnf_repo` to avoid direct
root installation from a URL if possible by downloading and verifying first.
Keep the changes scoped to `configure_pgedge_dnf_repo` and
`configure_pgedge_apt_repo`.
- Around line 146-174: The sign_rpms cleanup path can fail under set -u when GPG
setup variables are unset, which masks the real missing-key error. Update
sign_rpms to guard the cleanup in the KEY_ID check so it only removes
PRIVATE_KEY_FILE and GNUPGHOME when those variables are set, and keep the
failure flow intact after the gpg --list-secret-keys lookup. Use the sign_rpms
function and the KEY_ID empty-check block to locate the fix.

In `@packaging/coldfront-duckdb-extensions/build-deb.sh`:
- Around line 77-83: The post_build flow in build-deb.sh currently swallows the
missing-.deb case by falling back to echo, which lets failed package builds pass
silently. Update post_build and the sudo cp step so that when /tmp/pg_deb_build
has no .deb artifacts the script exits with a non-zero status instead of
continuing, while preserving the existing copy behavior for successful builds.
Use the existing rename_ddeb_packages and post_build functions as the hook
points for the check.

In `@packaging/lakekeeper/build-deb.sh`:
- Around line 70-75: The post_build step in build-deb.sh currently swallows
missing .deb artifacts by falling back to a log message, which lets the build
succeed silently. Update post_build so the .deb copy step in the packaging flow
fails the script when no package is produced, using the existing post_build and
rename_ddeb_packages flow to locate the problem and removing the silent-success
behavior from the sudo cp command.
- Around line 33-40: The release download flow in build-deb.sh extracts the
tarball and fetches LICENSE/NOTICE without verifying integrity first. Update the
packaging step around the tarball download/extraction and the LICENSE/NOTICE
fetches to validate the release asset against a published checksum or signature
before any extraction or packaging. Use the existing tarball download path and
the RELEASE_URL/REPO_RAW retrieval points to locate the change, and fail the
build if verification does not pass.

In `@packaging/pg_duckdb/build-deb.sh`:
- Around line 95-101: The post_build artifact staging in post_build is
swallowing real copy errors by using a broad fallback after sudo cp, so only the
expected “no .deb files” case should be handled specially. Update the copy step
to distinguish between an empty glob in "$BUILD_DIR" and genuine cp failures to
"/output", and make unexpected errors fail the script instead of printing the
fallback message. Keep the logic localized around post_build,
rename_ddeb_packages, and the sudo cp invocation.

---

Nitpick comments:
In @.github/workflows/release.yml:
- Around line 123-126: The Checkout steps in this workflow are persisting the
default GITHUB_TOKEN in .git/config, which is unnecessary since the workflow
uses explicit credentials elsewhere. Update every actions/checkout usage in the
release workflow to set persist-credentials to false, keeping the existing
fetch-depth and other settings intact. Use the Checkout step entries as the
targets for this change across the file.

In `@packaging/coldfront-bin/rpm/coldfront.spec`:
- Line 5: Remove the redundant BuildArch declaration from the spec so the
package relies on rpmbuild’s native architecture handling. Update the top-level
RPM spec definition near the existing debug_package macro, keeping the rest of
the package metadata unchanged and ensuring no other macros depend on the
removed BuildArch line.

In `@packaging/coldfront-duckdb-extensions/build-deb.sh`:
- Around line 80-81: The build script uses a predictable fixed /tmp path for the
deb build directory, which should be replaced with an unpredictable temporary
directory. Update the build flow around rename_ddeb_packages in build-deb.sh to
create the workspace with mktemp -d (or equivalent), store it in a variable, and
pass that variable instead of hardcoding /tmp/pg_deb_build so the temporary
location is unique per run.

In `@packaging/coldfront-duckdb-extensions/build-extensions.sh`:
- Around line 41-46: The build script is doing extra work by fully updating the
nested duckdb submodule only to delete and re-clone it later, and it is also
cloning vcpkg without a shallow fetch. Update build-extensions.sh so the initial
git submodule update for the ICE checkout excludes or deinitializes the duckdb
path before the clone replacement, and change the vcpkg clone to a shallow
checkout. Keep the fix localized around the submodule handling and the vcpkg
clone steps in the build flow.

In `@packaging/coldfront-duckdb-extensions/deb/debian/rules`:
- Around line 22-29: The SBOM generation and GPG signing logic in this
debian/rules fragment is duplicated across multiple packaging scripts, so move
the syft/gpg sequence into a shared helper and call it from
execute_before_dh_install. Add a reusable helper such as common/sign-sbom.sh
that accepts the package name and output directory (and optionally the source
dir), then update the packaging entry points like execute_before_dh_install and
the other debian/rules/RPM build sections to invoke that helper instead of
inlining the signing steps. Keep the helper responsible for key selection, SBOM
output naming, and signature file creation so future signing changes happen in
one place.

In `@packaging/lakekeeper/build-rpm.sh`:
- Around line 26-34: The download flow in build-rpm.sh fetches the Lakekeeper
tarball, LICENSE, and NOTICE with wget and packages them without verifying
integrity. Update the packaging step around the tarball download and the
LICENSE/NOTICE fetches to validate the artifacts against an expected SHA256
digest or release-published checksum before they are copied into
rpmbuild/SOURCES and signed; use the existing build-rpm.sh download logic and
the tarball/REPO_RAW variables to keep the verification tied to the fetched
release version.

In `@packaging/pg_duckdb/build-rpm.sh`:
- Around line 34-36: The curl staging step in build-rpm.sh downloads the tarball
in the build flow without verifying its integrity, so add a SHA256 (or similar)
verification immediately after the wget in the curl staging block. Use the
existing CURL_VERSION-specific download path and update the build logic to
compare the fetched tarball against a known-good pinned digest before placing it
into ~/rpmbuild/SOURCES, so the check is tied to the curl download step rather
than the later RPM build.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 251d16d8-f180-4243-aff6-620e18aa7c8e

📥 Commits

Reviewing files that changed from the base of the PR and between f74749f and f50a6e4.

📒 Files selected for processing (54)
  • .github/workflows/release.yml
  • .goreleaser.yaml
  • common/build.sh
  • common/common-functions.sh
  • packaging/coldfront-bin/build-deb.sh
  • packaging/coldfront-bin/build-rpm.sh
  • packaging/coldfront-bin/common.sh
  • packaging/coldfront-bin/deb/debian/control
  • packaging/coldfront-bin/deb/debian/pgedge-coldfront.conffiles
  • packaging/coldfront-bin/deb/debian/pgedge-coldfront.install
  • packaging/coldfront-bin/deb/debian/rules
  • packaging/coldfront-bin/deb/debian/source/format
  • packaging/coldfront-bin/rpm/coldfront.spec
  • packaging/coldfront-duckdb-extensions/build-deb.sh
  • packaging/coldfront-duckdb-extensions/build-extensions.sh
  • packaging/coldfront-duckdb-extensions/build-rpm.sh
  • packaging/coldfront-duckdb-extensions/common.sh
  • packaging/coldfront-duckdb-extensions/config/coldfront-duckdb-extensions.conf.sample
  • packaging/coldfront-duckdb-extensions/deb/debian/control
  • packaging/coldfront-duckdb-extensions/deb/debian/rules
  • packaging/coldfront-duckdb-extensions/deb/debian/source/format
  • packaging/coldfront-duckdb-extensions/rpm/coldfront-duckdb-extensions.spec
  • packaging/coldfront/build-deb.sh
  • packaging/coldfront/build-rpm.sh
  • packaging/coldfront/common.sh
  • packaging/coldfront/deb/debian/control.in
  • packaging/coldfront/deb/debian/pgedge-postgresql-coldfront.install
  • packaging/coldfront/deb/debian/pgversions
  • packaging/coldfront/deb/debian/rules
  • packaging/coldfront/deb/debian/source/format
  • packaging/coldfront/rpm/coldfront.spec
  • packaging/lakekeeper/README.md
  • packaging/lakekeeper/build-deb.sh
  • packaging/lakekeeper/build-rpm.sh
  • packaging/lakekeeper/common.sh
  • packaging/lakekeeper/common/lakekeeper.env
  • packaging/lakekeeper/common/lakekeeper.service
  • packaging/lakekeeper/deb/debian/control
  • packaging/lakekeeper/deb/debian/pgedge-lakekeeper.conffiles
  • packaging/lakekeeper/deb/debian/pgedge-lakekeeper.docs
  • packaging/lakekeeper/deb/debian/pgedge-lakekeeper.install
  • packaging/lakekeeper/deb/debian/postinst
  • packaging/lakekeeper/deb/debian/rules
  • packaging/lakekeeper/deb/debian/source/format
  • packaging/lakekeeper/rpm/lakekeeper.spec
  • packaging/pg_duckdb/build-deb.sh
  • packaging/pg_duckdb/build-rpm.sh
  • packaging/pg_duckdb/common.sh
  • packaging/pg_duckdb/deb/debian/control.in
  • packaging/pg_duckdb/deb/debian/pgedge-postgresql-pg-duckdb.install
  • packaging/pg_duckdb/deb/debian/pgversions
  • packaging/pg_duckdb/deb/debian/rules
  • packaging/pg_duckdb/deb/debian/source/format
  • packaging/pg_duckdb/rpm/pg_duckdb.spec

Comment thread common/common-functions.sh
Comment thread common/common-functions.sh
Comment thread common/common-functions.sh
Comment thread common/common-functions.sh
Comment thread common/common-functions.sh
Comment thread packaging/coldfront-duckdb-extensions/build-deb.sh
Comment thread packaging/lakekeeper/build-deb.sh
Comment thread packaging/lakekeeper/build-deb.sh
Comment thread packaging/pg_duckdb/build-deb.sh
@maqeel75
maqeel75 requested a review from dpage July 10, 2026 13:04

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
.github/workflows/release.yml (4)

735-740: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not block publication when an optional packaging matrix is skipped.

If has_ext_rpm/has_ext_deb is false, the corresponding package job is skipped, but these conditions still require its result to be success. That prevents publishing valid source packages when no extension cells exist. Allow success or an intentional skipped result, while still failing on real build failures.

Also applies to: 817-821

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 735 - 740, Update the publication
job conditions near the shown needs checks to treat optional package jobs as
successful when their result is either success or skipped, including the
corresponding conditions around the later referenced block. Preserve the
forced-push behavior and continue blocking publication when either packaging job
has a real failure or is cancelled.

1029-1034: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Upload the manifest even when publishing fails.

The artifact upload runs after the external publisher without if: always(). A publisher or Slack failure can therefore hide the manifest needed for debugging or promotion.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 1029 - 1034, Update the “Upload
aggregated manifest as workflow artifact” step to run unconditionally by adding
the workflow’s always() condition, so aggregated/manifest.json is uploaded even
when publishing or Slack notification steps fail.

736-740: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Allow force_push to override the tag-only gate.

Because github.ref_type == 'tag' is required unconditionally, force_push=true on a manual branch dispatch can never publish anything. Make the tag check an alternative to the explicitly enabled force-push path.

Also applies to: 818-821

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 736 - 740, Update the release
job’s if condition to make the tag requirement apply only to the normal
successful package path, while allowing the explicitly enabled force_push path
to run for manual branch dispatches. Preserve the existing cancelled-job
exclusions and package success requirements, and apply the same condition change
to the corresponding block noted in the comment.

80-91: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Pin the release helper repos to immutable commits. These git clone --depth 1 steps pull whatever is current on the default or multi-target branch and then execute it with signing keys and AWS credentials; a branch change could alter the release payload or expose secrets. Also applies to: 192-200, 474-484, 637-647, 700-710, 969-977

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 80 - 91, Update each
release-helper checkout, including the pgedge-parse-release-tag step and the
other referenced clone steps, to fetch and check out an immutable, reviewed
commit SHA rather than the moving default or multi-target branch. Preserve the
existing local action paths and subsequent uses, and apply the pinned revision
consistently to every listed helper repository.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In @.github/workflows/release.yml:
- Around line 735-740: Update the publication job conditions near the shown
needs checks to treat optional package jobs as successful when their result is
either success or skipped, including the corresponding conditions around the
later referenced block. Preserve the forced-push behavior and continue blocking
publication when either packaging job has a real failure or is cancelled.
- Around line 1029-1034: Update the “Upload aggregated manifest as workflow
artifact” step to run unconditionally by adding the workflow’s always()
condition, so aggregated/manifest.json is uploaded even when publishing or Slack
notification steps fail.
- Around line 736-740: Update the release job’s if condition to make the tag
requirement apply only to the normal successful package path, while allowing the
explicitly enabled force_push path to run for manual branch dispatches. Preserve
the existing cancelled-job exclusions and package success requirements, and
apply the same condition change to the corresponding block noted in the comment.
- Around line 80-91: Update each release-helper checkout, including the
pgedge-parse-release-tag step and the other referenced clone steps, to fetch and
check out an immutable, reviewed commit SHA rather than the moving default or
multi-target branch. Preserve the existing local action paths and subsequent
uses, and apply the pinned revision consistently to every listed helper
repository.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4471ca14-d827-454b-b376-7d00be160c8f

📥 Commits

Reviewing files that changed from the base of the PR and between 590a90f and 6a007ab.

📒 Files selected for processing (1)
  • .github/workflows/release.yml

@maqeel75

Copy link
Copy Markdown
Member Author

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)

.github/workflows/release.yml (4)> 735-740: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not block publication when an optional packaging matrix is skipped.
If has_ext_rpm/has_ext_deb is false, the corresponding package job is skipped, but these conditions still require its result to be success. That prevents publishing valid source packages when no extension cells exist. Allow success or an intentional skipped result, while still failing on real build failures.
Also applies to: 817-821

🤖 Prompt for AI Agents

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 735 - 740, Update the publication
job conditions near the shown needs checks to treat optional package jobs as
successful when their result is either success or skipped, including the
corresponding conditions around the later referenced block. Preserve the
forced-push behavior and continue blocking publication when either packaging job
has a real failure or is cancelled.

1029-1034: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Upload the manifest even when publishing fails.
The artifact upload runs after the external publisher without if: always(). A publisher or Slack failure can therefore hide the manifest needed for debugging or promotion.

🤖 Prompt for AI Agents

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 1029 - 1034, Update the “Upload
aggregated manifest as workflow artifact” step to run unconditionally by adding
the workflow’s always() condition, so aggregated/manifest.json is uploaded even
when publishing or Slack notification steps fail.

736-740: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Allow force_push to override the tag-only gate.
Because github.ref_type == 'tag' is required unconditionally, force_push=true on a manual branch dispatch can never publish anything. Make the tag check an alternative to the explicitly enabled force-push path.
Also applies to: 818-821

🤖 Prompt for AI Agents

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 736 - 740, Update the release
job’s if condition to make the tag requirement apply only to the normal
successful package path, while allowing the explicitly enabled force_push path
to run for manual branch dispatches. Preserve the existing cancelled-job
exclusions and package success requirements, and apply the same condition change
to the corresponding block noted in the comment.

80-91: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Pin the release helper repos to immutable commits. These git clone --depth 1 steps pull whatever is current on the default or multi-target branch and then execute it with signing keys and AWS credentials; a branch change could alter the release payload or expose secrets. Also applies to: 192-200, 474-484, 637-647, 700-710, 969-977

🤖 Prompt for AI Agents

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 80 - 91, Update each
release-helper checkout, including the pgedge-parse-release-tag step and the
other referenced clone steps, to fetch and check out an immutable, reviewed
commit SHA rather than the moving default or multi-target branch. Preserve the
existing local action paths and subsequent uses, and apply the pinned revision
consistently to every listed helper repository.

🤖 Prompt for all review comments with AI agents

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In @.github/workflows/release.yml:
- Around line 735-740: Update the publication job conditions near the shown
needs checks to treat optional package jobs as successful when their result is
either success or skipped, including the corresponding conditions around the
later referenced block. Preserve the forced-push behavior and continue blocking
publication when either packaging job has a real failure or is cancelled.
- Around line 1029-1034: Update the “Upload aggregated manifest as workflow
artifact” step to run unconditionally by adding the workflow’s always()
condition, so aggregated/manifest.json is uploaded even when publishing or Slack
notification steps fail.
- Around line 736-740: Update the release job’s if condition to make the tag
requirement apply only to the normal successful package path, while allowing the
explicitly enabled force_push path to run for manual branch dispatches. Preserve
the existing cancelled-job exclusions and package success requirements, and
apply the same condition change to the corresponding block noted in the comment.
- Around line 80-91: Update each release-helper checkout, including the
pgedge-parse-release-tag step and the other referenced clone steps, to fetch and
check out an immutable, reviewed commit SHA rather than the moving default or
multi-target branch. Preserve the existing local action paths and subsequent
uses, and apply the pinned revision consistently to every listed helper
repository.

ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4471ca14-d827-454b-b376-7d00be160c8f

📥 Commits
Reviewing files that changed from the base of the PR and between 590a90f and 6a007ab.

📒 Files selected for processing (1)

  • .github/workflows/release.yml

Fixed one valid issue, others either won't reach or as per design.

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.

1 participant