Skip to content

Commit 403d8f9

Browse files
author
dmitrivasilyev
committed
add launchpad publish rule
1 parent c45d671 commit 403d8f9

File tree

8 files changed

+458
-4
lines changed

8 files changed

+458
-4
lines changed

.github/workflows/build-packages.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@ jobs:
7878
- name: Build binaries in release mode
7979
run: JEMALLOC_SYS_WITH_MALLOC_CONF="dirty_decay_ms:30000,muzzy_decay_ms:30000,background_thread:true,metadata_thp:auto" cargo build --release
8080
- name: Prepare output dir
81-
run: mkdir -p ./build_package/usr/bin && install ./target/release/pg_doorman ./build_package/usr/bin && mkdir -p ./out/
81+
run: mkdir -p ./build_package/usr/bin && install ./target/release/pg_doorman ./build_package/usr/bin && install ./target/release/patroni_proxy ./build_package/usr/bin && mkdir -p ./out/
8282
- name: Check versions
83-
run: ./build_package/usr/bin/pg_doorman --version && cat /etc/debian_version
83+
run: ./build_package/usr/bin/pg_doorman --version && ./build_package/usr/bin/patroni_proxy --version && cat /etc/debian_version
8484
- name: Fix package name
8585
run: |
8686
export PACKAGE_NAME=pg_doorman-${{ matrix.image }}.deb &&
@@ -122,9 +122,9 @@ jobs:
122122
- name: Build binaries in release mode
123123
run: JEMALLOC_SYS_WITH_MALLOC_CONF="dirty_decay_ms:30000,muzzy_decay_ms:30000,background_thread:true,metadata_thp:auto" cargo build --release
124124
- name: Prepare output dir
125-
run: mkdir -p ./build_package/usr/bin && install ./target/release/pg_doorman ./build_package/usr/bin && mkdir -p ./out/
125+
run: mkdir -p ./build_package/usr/bin && install ./target/release/pg_doorman ./build_package/usr/bin && install ./target/release/patroni_proxy ./build_package/usr/bin && mkdir -p ./out/
126126
- name: Check versions
127-
run: ./build_package/usr/bin/pg_doorman --version && cat /etc/system-release
127+
run: ./build_package/usr/bin/pg_doorman --version && ./build_package/usr/bin/patroni_proxy --version && cat /etc/system-release
128128
- name: Fix package name
129129
run: |
130130
export PACKAGE_NAME=pg_doorman-${{ matrix.image }}.rpm &&
Lines changed: 330 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,330 @@
1+
name: Publish to Launchpad PPA
2+
3+
on:
4+
pull_request:
5+
release:
6+
types: [published]
7+
8+
permissions:
9+
contents: read
10+
11+
env:
12+
# Last 4 Ubuntu LTS/stable versions
13+
UBUNTU_VERSIONS: "jammy noble oracular plucky"
14+
# jammy = 22.04 LTS
15+
# noble = 24.04 LTS
16+
# oracular = 24.10
17+
# plucky = 25.04
18+
PPA_NAME: "ppa:pg-doorman/pg-doorman"
19+
RUST_VERSION: "1.87.0"
20+
21+
jobs:
22+
verify-version:
23+
name: Verify tag version matches Cargo.toml
24+
runs-on: ubuntu-latest
25+
outputs:
26+
version: ${{ steps.get_version.outputs.version }}
27+
steps:
28+
- name: Checkout Repository
29+
uses: actions/checkout@v4
30+
31+
- name: Get and verify version
32+
id: get_version
33+
run: |
34+
# Extract version from Cargo.toml
35+
CARGO_VERSION=$(grep '^version =' Cargo.toml | head -1 | cut -d '"' -f2)
36+
echo "Cargo.toml version: $CARGO_VERSION"
37+
38+
# For release events, verify tag matches Cargo.toml version
39+
if [ "${{ github.event_name }}" = "release" ]; then
40+
# Extract version from git tag (remove 'v' prefix)
41+
TAG_VERSION=${GITHUB_REF_NAME#v}
42+
echo "Git tag version: $TAG_VERSION"
43+
44+
# Compare versions
45+
if [ "$CARGO_VERSION" != "$TAG_VERSION" ]; then
46+
echo "Error: Version mismatch between Cargo.toml ($CARGO_VERSION) and git tag ($TAG_VERSION)"
47+
exit 1
48+
fi
49+
else
50+
echo "Pull request build - skipping tag verification"
51+
fi
52+
53+
echo "version=$CARGO_VERSION" >> $GITHUB_OUTPUT
54+
55+
prepare-source-packages:
56+
name: Prepare source packages for Launchpad
57+
needs: [verify-version]
58+
runs-on: ubuntu-latest
59+
container:
60+
image: ubuntu:24.04
61+
env:
62+
DEBIAN_FRONTEND: noninteractive
63+
64+
steps:
65+
- name: Checkout Repository
66+
uses: actions/checkout@v4
67+
with:
68+
fetch-depth: 0
69+
70+
- name: Install build dependencies
71+
run: |
72+
apt-get update
73+
apt-get install -y \
74+
git \
75+
devscripts \
76+
debhelper \
77+
dput \
78+
gnupg \
79+
wget \
80+
build-essential \
81+
pkg-config \
82+
libssl-dev \
83+
cmake \
84+
clang \
85+
g++ \
86+
ca-certificates
87+
88+
- name: Install Rust
89+
run: |
90+
wget -q https://static.rust-lang.org/dist/rust-${{ env.RUST_VERSION }}-x86_64-unknown-linux-gnu.tar.gz -O /tmp/rust.tar.gz
91+
cd /tmp && tar xf rust.tar.gz && ./rust-*-x86_64-unknown-linux-gnu/install.sh
92+
93+
- name: Import GPG key
94+
env:
95+
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
96+
run: |
97+
echo "$GPG_PRIVATE_KEY" | gpg --batch --no-tty --import
98+
# Get the key ID
99+
GPG_KEY_ID=$(gpg --list-secret-keys --keyid-format LONG | grep sec | head -1 | awk '{print $2}' | cut -d'/' -f2)
100+
echo "GPG_KEY_ID=$GPG_KEY_ID" >> $GITHUB_ENV
101+
# Trust the key automatically without TTY
102+
echo -e "5\ny\n" | gpg --batch --no-tty --command-fd 0 --expert --edit-key $GPG_KEY_ID trust
103+
# Configure GPG for non-interactive use (fix "Inappropriate ioctl for device" error)
104+
mkdir -p ~/.gnupg
105+
echo "use-agent" >> ~/.gnupg/gpg.conf
106+
echo "pinentry-mode loopback" >> ~/.gnupg/gpg.conf
107+
echo "allow-loopback-pinentry" >> ~/.gnupg/gpg-agent.conf
108+
echo "RELOADAGENT" | gpg-connect-agent || true
109+
110+
- name: Create vendor tarball
111+
run: |
112+
cargo vendor
113+
tar czf vendor.tar.gz vendor/
114+
115+
- name: Build source packages for each Ubuntu version
116+
env:
117+
VERSION: ${{ needs.verify-version.outputs.version }}
118+
run: |
119+
set -e
120+
121+
# Verify all required tools are installed
122+
echo "Verifying required tools..."
123+
for tool in dput debuild gpg tar; do
124+
if ! which $tool > /dev/null 2>&1; then
125+
echo "Error: Required tool '$tool' is not installed"
126+
exit 1
127+
fi
128+
echo " $tool: $(which $tool)"
129+
done
130+
echo "All required tools are available"
131+
132+
# Create output directory for all packages
133+
mkdir -p /tmp/packages
134+
135+
for DISTRO in $UBUNTU_VERSIONS; do
136+
echo "=========================================="
137+
echo "Building for Ubuntu $DISTRO"
138+
echo "=========================================="
139+
140+
# Create a clean working directory
141+
WORK_DIR=$(mktemp -d)
142+
cp -r . "$WORK_DIR/pg-doorman-${VERSION}"
143+
cd "$WORK_DIR/pg-doorman-${VERSION}"
144+
145+
# Remove .git directory to reduce size
146+
rm -rf .git
147+
148+
# Include vendor directory for offline build
149+
tar xzf vendor.tar.gz
150+
151+
# Generate changelog for this distribution
152+
cat > debian/changelog << EOF
153+
pg-doorman (${VERSION}~${DISTRO}) ${DISTRO}; urgency=medium
154+
155+
* Release version ${VERSION}
156+
* PostgreSQL connection pooler and proxy
157+
* Includes pg_doorman and patroni_proxy binaries
158+
159+
-- pg-doorman maintainers <pg-doorman@launchpad.net> $(date -R)
160+
EOF
161+
162+
# Create the source package
163+
cd "$WORK_DIR"
164+
tar czf "pg-doorman_${VERSION}~${DISTRO}.orig.tar.gz" "pg-doorman-${VERSION}"
165+
cd "pg-doorman-${VERSION}"
166+
167+
# Build source package (unsigned first, then sign manually)
168+
# Using dpkg-buildpackage directly to avoid debsign TTY issues
169+
dpkg-buildpackage -us -uc -ui -S -sa
170+
171+
# Sign the .dsc and .changes files manually with gpg
172+
cd "$WORK_DIR"
173+
debsign -k${{ env.GPG_KEY_ID }} --no-re-sign -p"gpg --batch --no-tty --pinentry-mode loopback" pg-doorman_${VERSION}~${DISTRO}_source.changes
174+
175+
# Copy built packages to output directory
176+
cp "$WORK_DIR"/pg-doorman_${VERSION}~${DISTRO}* /tmp/packages/
177+
178+
# Cleanup working directory
179+
cd /
180+
rm -rf "$WORK_DIR"
181+
182+
echo "Successfully built package for Ubuntu $DISTRO"
183+
done
184+
185+
echo "=========================================="
186+
echo "All packages built successfully"
187+
echo "=========================================="
188+
ls -la /tmp/packages/
189+
190+
- name: Upload source packages artifact
191+
uses: actions/upload-artifact@v4
192+
with:
193+
name: launchpad-source-packages
194+
path: /tmp/packages/
195+
196+
test-package-installation:
197+
name: Test package installation (${{ matrix.distro }})
198+
needs: [verify-version, prepare-source-packages]
199+
runs-on: ubuntu-latest
200+
strategy:
201+
matrix:
202+
include:
203+
- distro: jammy
204+
image: ubuntu:22.04
205+
- distro: noble
206+
image: ubuntu:24.04
207+
- distro: oracular
208+
image: ubuntu:24.10
209+
- distro: plucky
210+
image: ubuntu:25.04
211+
container:
212+
image: ${{ matrix.image }}
213+
env:
214+
DEBIAN_FRONTEND: noninteractive
215+
216+
steps:
217+
- name: Download source packages
218+
uses: actions/download-artifact@v4
219+
with:
220+
name: launchpad-source-packages
221+
path: /tmp/packages
222+
223+
- name: Install build dependencies
224+
run: |
225+
apt-get update
226+
apt-get install -y \
227+
build-essential \
228+
devscripts \
229+
debhelper \
230+
pkg-config \
231+
libssl-dev \
232+
cmake \
233+
clang \
234+
g++ \
235+
wget \
236+
ca-certificates
237+
238+
- name: Install Rust
239+
run: |
240+
wget -q https://static.rust-lang.org/dist/rust-${{ env.RUST_VERSION }}-x86_64-unknown-linux-gnu.tar.gz -O /tmp/rust.tar.gz
241+
cd /tmp && tar xf rust.tar.gz && ./rust-*-x86_64-unknown-linux-gnu/install.sh
242+
243+
- name: Build and install package
244+
env:
245+
VERSION: ${{ needs.verify-version.outputs.version }}
246+
DISTRO: ${{ matrix.distro }}
247+
run: |
248+
set -e
249+
cd /tmp/packages
250+
251+
echo "=========================================="
252+
echo "Building binary package for Ubuntu $DISTRO"
253+
echo "=========================================="
254+
255+
# Extract source package
256+
dpkg-source -x pg-doorman_${VERSION}~${DISTRO}.dsc
257+
cd pg-doorman-${VERSION}~${DISTRO}
258+
259+
# Build binary package
260+
dpkg-buildpackage -us -uc -b
261+
262+
# Install the package
263+
cd ..
264+
dpkg -i pg-doorman_${VERSION}~${DISTRO}_*.deb || apt-get install -f -y
265+
266+
echo "=========================================="
267+
echo "Verifying installation"
268+
echo "=========================================="
269+
270+
# Verify binaries are installed and working
271+
which pg_doorman
272+
which patroni_proxy
273+
pg_doorman --version
274+
patroni_proxy --version
275+
276+
echo "=========================================="
277+
echo "Package installation test passed for Ubuntu $DISTRO"
278+
echo "=========================================="
279+
280+
upload-to-launchpad:
281+
name: Upload to Launchpad PPA
282+
needs: [verify-version, prepare-source-packages]
283+
if: github.event_name == 'release'
284+
runs-on: ubuntu-latest
285+
container:
286+
image: ubuntu:24.04
287+
env:
288+
DEBIAN_FRONTEND: noninteractive
289+
steps:
290+
- name: Download source packages
291+
uses: actions/download-artifact@v4
292+
with:
293+
name: launchpad-source-packages
294+
path: /tmp/packages
295+
296+
- name: Install dput
297+
run: |
298+
apt-get update
299+
apt-get install -y dput gnupg
300+
301+
- name: Import GPG key
302+
env:
303+
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
304+
run: |
305+
echo "$GPG_PRIVATE_KEY" | gpg --batch --no-tty --import
306+
GPG_KEY_ID=$(gpg --list-secret-keys --keyid-format LONG | grep sec | head -1 | awk '{print $2}' | cut -d'/' -f2)
307+
echo "GPG_KEY_ID=$GPG_KEY_ID" >> $GITHUB_ENV
308+
309+
- name: Upload source packages to Launchpad PPA
310+
if: github.event_name == 'release'
311+
env:
312+
VERSION: ${{ needs.verify-version.outputs.version }}
313+
run: |
314+
set -e
315+
316+
cd /tmp/packages
317+
318+
for DISTRO in $UBUNTU_VERSIONS; do
319+
echo "=========================================="
320+
echo "Uploading package for Ubuntu $DISTRO"
321+
echo "=========================================="
322+
323+
dput ${{ env.PPA_NAME }} "pg-doorman_${VERSION}~${DISTRO}_source.changes"
324+
325+
echo "Successfully uploaded package for Ubuntu $DISTRO"
326+
done
327+
328+
echo "=========================================="
329+
echo "All packages uploaded to Launchpad PPA"
330+
echo "=========================================="

debian/control

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Source: pg-doorman
2+
Section: database
3+
Priority: optional
4+
Maintainer: pg-doorman maintainers <pg-doorman@launchpad.net>
5+
Build-Depends: debhelper-compat (= 13),
6+
libssl-dev,
7+
pkg-config,
8+
cmake,
9+
clang,
10+
g++
11+
Standards-Version: 4.6.0
12+
Homepage: https://github.com/ozontech/pg_doorman
13+
Vcs-Git: https://github.com/ozontech/pg_doorman.git
14+
Vcs-Browser: https://github.com/ozontech/pg_doorman
15+
16+
Package: pg-doorman
17+
Architecture: amd64
18+
Depends: ${shlibs:Depends}, ${misc:Depends}, openssl
19+
Description: PostgreSQL connection pooler and proxy
20+
pg_doorman is a high-performance PostgreSQL connection pooler and proxy
21+
written in Rust. It provides efficient connection pooling, load balancing,
22+
and query routing capabilities for PostgreSQL databases.
23+
.
24+
This package includes:
25+
- pg_doorman: main PostgreSQL connection pooler and proxy
26+
- patroni_proxy: Patroni integration proxy for high availability setups

0 commit comments

Comments
 (0)