From 5c32a44f191572a485ee447af6741e7b9116ed3d Mon Sep 17 00:00:00 2001 From: Kaushik Iska Date: Tue, 7 Apr 2026 16:30:58 -0500 Subject: [PATCH 1/2] Add .deb packaging workflow with GitHub Releases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Build .deb packages for PG 16-18 on Ubuntu 22.04 (amd64 + arm64) and upload them to GitHub Releases for public unauthenticated downloads. - main pushes → rolling `dev` pre-release - customer-* pushes → rolling `customer-` pre-release - v* tags → attached to the version release --- .github/workflows/deb.yml | 139 ++++++++++++++++++++++++++++++++++++++ nfpm.yml | 25 +++++++ 2 files changed, 164 insertions(+) create mode 100644 .github/workflows/deb.yml create mode 100644 nfpm.yml diff --git a/.github/workflows/deb.yml b/.github/workflows/deb.yml new file mode 100644 index 0000000..05159f4 --- /dev/null +++ b/.github/workflows/deb.yml @@ -0,0 +1,139 @@ +name: 📦 Build .deb Packages + +on: + push: + branches: [main, customer-*] + tags: ["v*"] + +permissions: + contents: write + +jobs: + build: + name: 📦 PG ${{ matrix.pg }} ${{ matrix.os.arch }} + runs-on: ${{ matrix.os.runner }} + strategy: + fail-fast: false + matrix: + pg: [18, 17, 16] + os: + - { arch: amd64, runner: ubuntu-22.04 } + - { arch: arm64, runner: ubuntu-22.04-arm } + steps: + - name: Add PostgreSQL APT Repository + run: | + sudo apt-get update + sudo apt-get install -y curl ca-certificates gnupg + curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg >/dev/null + echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list + sudo apt-get update + + - name: Install Build Dependencies + run: | + sudo apt-get install -y \ + postgresql-${{ matrix.pg }} \ + postgresql-server-dev-${{ matrix.pg }} \ + cmake ninja-build g++ libssl-dev + + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + fetch-depth: 0 + + - name: Configure + run: | + cmake --preset release \ + -DPG_CONFIG=/usr/lib/postgresql/${{ matrix.pg }}/bin/pg_config + + - name: Build + run: cmake --build build --parallel + + - name: Install to Staging Directory + run: DESTDIR=${{ github.workspace }}/dest cmake --install build + + - name: Extract Version + id: meta + run: | + VERSION=$(jq -r '.version' META.json) + PKG_NAME="pg-stat-ch-${VERSION}-pg${{ matrix.pg }}-${{ matrix.os.arch }}" + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + echo "pkg_name=$PKG_NAME" >> "$GITHUB_OUTPUT" + + - name: Install nfpm + run: | + curl -fsSL -o /tmp/nfpm.deb https://github.com/goreleaser/nfpm/releases/download/v2.46.0/nfpm_2.46.0_${{ matrix.os.arch }}.deb + sudo dpkg -i /tmp/nfpm.deb + + - name: Build .deb + env: + PG_MAJOR: ${{ matrix.pg }} + VERSION: ${{ steps.meta.outputs.version }} + ARCH: ${{ matrix.os.arch }} + DESTDIR: ${{ github.workspace }}/dest + run: | + envsubst < nfpm.yml > nfpm-resolved.yml + nfpm package -f nfpm-resolved.yml -p deb -t ${{ steps.meta.outputs.pkg_name }}.deb + + - name: Upload .deb Artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ steps.meta.outputs.pkg_name }} + path: ${{ steps.meta.outputs.pkg_name }}.deb + + release: + name: 🚀 Upload to Release + needs: build + runs-on: ubuntu-latest + steps: + - name: Download All .deb Artifacts + uses: actions/download-artifact@v4 + with: + path: debs + pattern: pg-stat-ch-* + merge-multiple: true + + - name: Determine Release Tag + id: tag + run: | + if [[ "$GITHUB_REF" == refs/tags/v* ]]; then + echo "tag=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" + echo "prerelease=false" >> "$GITHUB_OUTPUT" + elif [[ "$GITHUB_REF" == refs/heads/main ]]; then + echo "tag=dev" >> "$GITHUB_OUTPUT" + echo "prerelease=true" >> "$GITHUB_OUTPUT" + else + # customer-foo -> customer-foo + BRANCH="${GITHUB_REF#refs/heads/}" + echo "tag=$BRANCH" >> "$GITHUB_OUTPUT" + echo "prerelease=true" >> "$GITHUB_OUTPUT" + fi + + - name: Create or Update Release + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ steps.tag.outputs.tag }} + PRERELEASE: ${{ steps.tag.outputs.prerelease }} + run: | + ls -la debs/ + + if [[ "$PRERELEASE" == "true" ]]; then + # Create the release if it doesn't exist yet. + gh release view "$TAG" -R "$GITHUB_REPOSITORY" >/dev/null 2>&1 || \ + gh release create "$TAG" -R "$GITHUB_REPOSITORY" \ + --prerelease \ + --title "$TAG" \ + --notes "Rolling pre-release for \`$TAG\`. Updated on every push." + + # Upload .deb files, replacing any existing ones. + gh release upload "$TAG" debs/*.deb -R "$GITHUB_REPOSITORY" --clobber + else + # For version tags, the release is created by release.yml. + # Wait briefly for it to exist, then attach .debs. + for i in 1 2 3 4 5; do + gh release view "$TAG" -R "$GITHUB_REPOSITORY" >/dev/null 2>&1 && break + echo "Waiting for release $TAG to be created..." + sleep 10 + done + gh release upload "$TAG" debs/*.deb -R "$GITHUB_REPOSITORY" --clobber + fi diff --git a/nfpm.yml b/nfpm.yml new file mode 100644 index 0000000..ea3ea5a --- /dev/null +++ b/nfpm.yml @@ -0,0 +1,25 @@ +name: pg-stat-ch +arch: ${ARCH} +version: ${VERSION} +release: 1 +platform: linux +section: database +priority: optional +maintainer: "Kaushik Iska " +description: "PostgreSQL Query Telemetry Exporter to ClickHouse for PostgreSQL ${PG_MAJOR}" +vendor: ClickHouse +homepage: https://github.com/ClickHouse/pg_stat_ch +license: Apache-2.0 + +depends: + - postgresql-${PG_MAJOR} + - libssl3 + +contents: + # Extension SQL and control files. + - src: ${DESTDIR}/usr/share/postgresql/${PG_MAJOR}/extension/*.* + dst: /usr/share/postgresql/${PG_MAJOR}/extension/ + + # Shared library. + - src: ${DESTDIR}/usr/lib/postgresql/${PG_MAJOR}/lib/pg_stat_ch.so + dst: /usr/lib/postgresql/${PG_MAJOR}/lib/pg_stat_ch.so From d43dcf8e41faf3d8875cc0fefa6a0ad2d2734113 Mon Sep 17 00:00:00 2001 From: Kaushik Iska Date: Tue, 7 Apr 2026 16:41:09 -0500 Subject: [PATCH 2/2] fix: address Copilot review comments on deb packaging - Use HTTPS for PostgreSQL APT repo to prevent MITM risk - Include PG major version in package name for co-installability - Create release if missing instead of fragile wait loop --- .github/workflows/deb.yml | 21 +++++++++------------ nfpm.yml | 2 +- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/.github/workflows/deb.yml b/.github/workflows/deb.yml index 05159f4..ae6d396 100644 --- a/.github/workflows/deb.yml +++ b/.github/workflows/deb.yml @@ -25,7 +25,7 @@ jobs: sudo apt-get update sudo apt-get install -y curl ca-certificates gnupg curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg >/dev/null - echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list + echo "deb https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list sudo apt-get update - name: Install Build Dependencies @@ -124,16 +124,13 @@ jobs: --prerelease \ --title "$TAG" \ --notes "Rolling pre-release for \`$TAG\`. Updated on every push." - - # Upload .deb files, replacing any existing ones. - gh release upload "$TAG" debs/*.deb -R "$GITHUB_REPOSITORY" --clobber else - # For version tags, the release is created by release.yml. - # Wait briefly for it to exist, then attach .debs. - for i in 1 2 3 4 5; do - gh release view "$TAG" -R "$GITHUB_REPOSITORY" >/dev/null 2>&1 && break - echo "Waiting for release $TAG to be created..." - sleep 10 - done - gh release upload "$TAG" debs/*.deb -R "$GITHUB_REPOSITORY" --clobber + # For version tags, ensure the release exists before uploading assets. + gh release view "$TAG" -R "$GITHUB_REPOSITORY" >/dev/null 2>&1 || \ + gh release create "$TAG" -R "$GITHUB_REPOSITORY" \ + --title "$TAG" \ + --notes "Release $TAG" fi + + # Upload .deb files, replacing any existing ones. + gh release upload "$TAG" debs/*.deb -R "$GITHUB_REPOSITORY" --clobber diff --git a/nfpm.yml b/nfpm.yml index ea3ea5a..c3eae05 100644 --- a/nfpm.yml +++ b/nfpm.yml @@ -1,4 +1,4 @@ -name: pg-stat-ch +name: postgresql-${PG_MAJOR}-pg-stat-ch arch: ${ARCH} version: ${VERSION} release: 1