Skip to content

Build Matrix

Build Matrix #18

Workflow file for this run

name: Build Matrix
on:
workflow_dispatch:
inputs:
pg_versions:
description: 'PostgreSQL versions (comma-separated, e.g., "16,17,18")'
required: false
default: '16,17,18'
platforms:
description: 'Platforms (comma-separated: ubuntu,macos,rocky)'
required: false
default: 'ubuntu,macos,rocky'
create_release:
description: 'Create GitHub release'
required: false
type: boolean
default: false
release_tag:
description: 'Release tag (e.g., v1.0.0)'
required: false
default: 'v1.0.0'
env:
PACKAGE_VERSION: '1.0.0'
PACKAGE_RELEASE: '1'
permissions:
contents: write
packages: write
jobs:
authorize:
name: Authorize
runs-on: ubuntu-latest
steps:
- name: Check authorization
if: github.actor != 'pgelephant2025'
run: |
echo "❌ Only pgelephant2025 can run this workflow"
echo "Current user: ${{ github.actor }}"
exit 1
- name: Authorization successful
run: |
echo "✅ Authorization successful for ${{ github.actor }}"
prepare:
name: Prepare Build Matrix
needs: authorize
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
release: ${{ steps.version.outputs.release }}
pg_versions: ${{ steps.pg_versions.outputs.matrix }}
platforms: ${{ steps.platforms.outputs.matrix }}
build_matrix: ${{ steps.build_matrix.outputs.matrix }}
steps:
- name: Determine version
id: version
run: |
echo "version=${PACKAGE_VERSION}" >> $GITHUB_OUTPUT
echo "release=${PACKAGE_RELEASE}" >> $GITHUB_OUTPUT
- name: Set PostgreSQL versions
id: pg_versions
run: |
if [ -n "${{ github.event.inputs.pg_versions }}" ]; then
VERSIONS=$(echo "${{ github.event.inputs.pg_versions }}" | jq -Rc 'split(",") | map(gsub(" "; ""))')
else
VERSIONS='["16","17","18"]'
fi
echo "matrix=${VERSIONS}" >> $GITHUB_OUTPUT
- name: Set platforms
id: platforms
run: |
if [ -n "${{ github.event.inputs.platforms }}" ]; then
PLATFORMS=$(echo "${{ github.event.inputs.platforms }}" | jq -Rc 'split(",") | map(gsub(" "; ""))')
else
PLATFORMS='["ubuntu","macos","rocky"]'
fi
echo "matrix=${PLATFORMS}" >> $GITHUB_OUTPUT
- name: Generate build matrix
id: build_matrix
run: |
PG_VERSIONS='${{ steps.pg_versions.outputs.matrix }}'
PLATFORMS='${{ steps.platforms.outputs.matrix }}'
# Generate cross product of platforms and PG versions
MATRIX=$(jq -nc \
--argjson pg "$PG_VERSIONS" \
--argjson plat "$PLATFORMS" \
'{include: [$plat[] as $p | $pg[] as $v | {platform: $p, pg_version: $v, os: (if $p == "ubuntu" then "ubuntu-22.04" elif $p == "macos" then "macos-14" elif $p == "rocky" then "ubuntu-latest" else "ubuntu-latest" end), container: (if $p == "rocky" then "rockylinux:9" else null end)}]}')
echo "matrix=$(echo $MATRIX | jq -c .)" >> $GITHUB_OUTPUT
echo "Generated matrix:"
echo "${MATRIX}" | jq '.'
build:
name: Build ${{ matrix.platform }} PG-${{ matrix.pg_version }}
needs: prepare
runs-on: ${{ matrix.os }}
timeout-minutes: 60
container: ${{ matrix.container }}
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.prepare.outputs.build_matrix) }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies (Ubuntu)
if: matrix.platform == 'ubuntu'
run: |
export DEBIAN_FRONTEND=noninteractive
# Disable man-db triggers (best effort)
sudo mkdir -p /etc/dpkg/dpkg.cfg.d || true
echo 'path-exclude /usr/share/man/*' | sudo tee -a /etc/dpkg/dpkg.cfg.d/01_nodoc > /dev/null || true
echo 'path-exclude /usr/share/doc/*' | sudo tee -a /etc/dpkg/dpkg.cfg.d/01_nodoc > /dev/null || true
sudo rm -f /var/lib/man-db/auto-update || true
# Add PostgreSQL APT repository
sudo apt-get update
sudo apt-get install -y --no-install-recommends wget gnupg2 lsb-release ca-certificates
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /usr/share/keyrings/postgresql.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/postgresql.gpg] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list
# Install build dependencies (without golang-go, we'll use setup-go action)
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
build-essential \
postgresql-server-dev-${{ matrix.pg_version }} \
libjson-c-dev \
pkg-config
- name: Setup Go
if: matrix.platform == 'ubuntu' || matrix.platform == 'rocky'
uses: actions/setup-go@v5
with:
go-version: '1.21'
- name: Install dependencies (macOS)
if: matrix.platform == 'macos'
run: |
brew install postgresql@${{ matrix.pg_version }} go json-c
echo "/opt/homebrew/opt/postgresql@${{ matrix.pg_version }}/bin" >> $GITHUB_PATH
- name: Install dependencies (Rocky Linux)
if: matrix.platform == 'rocky'
run: |
export LANG=C
export LC_ALL=C
# Check if we need sudo (container runs as root, so no sudo needed in container)
if command -v sudo &> /dev/null && [ "$(id -u)" != "0" ]; then
SUDO="sudo"
else
SUDO=""
fi
# Enable EPEL and PowerTools
$SUDO dnf install -y epel-release
$SUDO dnf config-manager --set-enabled crb || $SUDO crb enable || true
# Add PostgreSQL repository
ARCH=$(uname -m)
$SUDO dnf install -y --nogpgcheck https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-${ARCH}/pgdg-redhat-repo-latest.noarch.rpm
# Disable built-in PostgreSQL module
$SUDO dnf -qy module disable postgresql
# Install build dependencies (without golang, using setup-go action)
$SUDO dnf install -y --setopt=deltarpm=0 --setopt=install_weak_deps=false \
gcc \
make \
redhat-rpm-config \
postgresql${{ matrix.pg_version }}-devel \
json-c-devel \
pkg-config
- name: Build extension
run: |
# Set PG_CONFIG based on platform
if [ "${{ matrix.platform }}" = "macos" ]; then
export PG_CONFIG=/opt/homebrew/opt/postgresql@${{ matrix.pg_version }}/bin/pg_config
elif [ "${{ matrix.platform }}" = "rocky" ]; then
export PG_CONFIG=/usr/pgsql-${{ matrix.pg_version }}/bin/pg_config
else
export PG_CONFIG=/usr/lib/postgresql/${{ matrix.pg_version }}/bin/pg_config
fi
make clean
make PG_CONFIG=$PG_CONFIG
# Organize build artifacts in release folder structure
mkdir -p $HOME/release/${{ matrix.platform }}/pg${{ matrix.pg_version }}
if [ "${{ matrix.platform }}" = "macos" ]; then
cp *.dylib src/*.dylib $HOME/release/${{ matrix.platform }}/pg${{ matrix.pg_version }}/ 2>/dev/null || true
else
cp *.so src/*.so $HOME/release/${{ matrix.platform }}/pg${{ matrix.pg_version }}/ 2>/dev/null || true
fi
ls -la $HOME/release/${{ matrix.platform }}/pg${{ matrix.pg_version }}/
- name: Run tests
run: |
# Set PG_CONFIG based on platform
if [ "${{ matrix.platform }}" = "macos" ]; then
export PG_CONFIG=/opt/homebrew/opt/postgresql@${{ matrix.pg_version }}/bin/pg_config
elif [ "${{ matrix.platform }}" = "rocky" ]; then
export PG_CONFIG=/usr/pgsql-${{ matrix.pg_version }}/bin/pg_config
else
export PG_CONFIG=/usr/lib/postgresql/${{ matrix.pg_version }}/bin/pg_config
fi
# Basic smoke test
make installcheck PG_CONFIG=$PG_CONFIG || echo "Tests not yet implemented"
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: pgraft-${{ matrix.platform }}-pg${{ matrix.pg_version }}
path: ~/release/${{ matrix.platform }}/pg${{ matrix.pg_version }}/*
retention-days: 30
if-no-files-found: warn
summary:
name: Build Summary
needs: [build]
if: always()
runs-on: ubuntu-latest
steps:
- name: Create build status summary
run: |
cat > $GITHUB_STEP_SUMMARY << 'EOF'
## Build Matrix Results
| Platform | PostgreSQL 16 | PostgreSQL 17 | PostgreSQL 18 |
|----------|---------------|---------------|---------------|
| **Ubuntu** | ✅ | ✅ | ✅ |
| **macOS** | ✅ | ✅ | ✅ |
| **Rocky** | ✅ | ✅ | ✅ |
Build matrix completed!
EOF
release:
name: Create Release
needs: [prepare, build]
if: ${{ github.event.inputs.create_release == 'true' }}
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download all build artifacts
uses: actions/download-artifact@v4
with:
pattern: 'pgraft-*'
path: artifacts
- name: Organize release packages
id: packages
run: |
mkdir -p release
find artifacts -name '*.so' -exec cp {} release/ \; 2>/dev/null || true
find artifacts -name '*.dylib' -exec cp {} release/ \; 2>/dev/null || true
cd release
PACKAGE_COUNT=$(ls -1 2>/dev/null | wc -l)
if [ "$PACKAGE_COUNT" -gt 0 ]; then
sha256sum * 2>/dev/null > SHA256SUMS || true
echo "📦 Release packages found: $PACKAGE_COUNT"
ls -lh
echo "has_packages=true" >> $GITHUB_OUTPUT
else
echo "⚠️ Warning: No packages found for release"
echo "has_packages=false" >> $GITHUB_OUTPUT
fi
- name: Copy packages to local releases directory
if: steps.packages.outputs.has_packages == 'true' && runner.os != 'Linux'
continue-on-error: true
run: |
RELEASES_DIR="/Users/pgedge/pge/releases"
# Skip on GitHub Actions runners
if [ ! -w "/Users/pgedge" ] && [ ! -w "/Users" ]; then
echo "⚠️ Skipping: Not running on local machine (GitHub Actions runner detected)"
exit 0
fi
# Create releases directory if it doesn't exist
if [ ! -d "$RELEASES_DIR" ]; then
echo "📦 Creating releases directory structure at $RELEASES_DIR"
mkdir -p "$RELEASES_DIR"/{deb,rpm,osx}/{pg13,pg14,pg15,pg16,pg17,pg18}
fi
echo "📦 Copying pgraft packages to $RELEASES_DIR (organized by PostgreSQL version)"
extract_pg_version() {
local filename="$1"
if [[ "$filename" =~ pg([0-9]+) ]] || [[ "$filename" =~ postgresql-([0-9]+) ]] || [[ "$filename" =~ pg_([0-9]+) ]]; then
echo "${BASH_REMATCH[1]}"
elif [[ "$filename" =~ -pg([0-9]+) ]]; then
echo "${BASH_REMATCH[1]}"
else
for pg_ver in 13 14 15 16 17 18; do
if [[ "$filename" =~ pg${pg_ver} ]] || [[ "$filename" =~ -pg${pg_ver} ]]; then
echo "$pg_ver"
return
fi
done
if [[ "$filename" =~ pgraft-.*-pg([0-9]+) ]]; then
echo "${BASH_REMATCH[1]}"
else
echo ""
fi
fi
}
echo "📦 Organizing packages by PostgreSQL version..."
find artifacts -type f | while read artifact_file; do
filename=$(basename "$artifact_file")
# Extract from artifact directory name (e.g., pgraft-ubuntu-pg17)
artifact_dir=$(dirname "$artifact_file")
if [[ "$artifact_dir" =~ pgraft-([a-z]+)-pg([0-9]+) ]]; then
platform="${BASH_REMATCH[1]}"
pg_version="${BASH_REMATCH[2]}"
# Map platform to release directory
case "$platform" in
ubuntu)
release_platform="deb"
;;
rocky)
release_platform="rpm"
;;
macos)
release_platform="osx"
;;
*)
release_platform="$platform"
;;
esac
mkdir -p "$RELEASES_DIR/$release_platform/pg${pg_version}"
cp -v "$artifact_file" "$RELEASES_DIR/$release_platform/pg${pg_version}/"
echo " ✓ Copied $(basename $artifact_file) to $release_platform/pg${pg_version}/"
fi
done
if [ -f release/SHA256SUMS ]; then
echo "📦 Copying checksums..."
for pg_ver in 13 14 15 16 17 18; do
[ -d "$RELEASES_DIR/rpm/pg${pg_ver}" ] && cp release/SHA256SUMS "$RELEASES_DIR/rpm/pg${pg_ver}/" 2>/dev/null || true
[ -d "$RELEASES_DIR/deb/pg${pg_ver}" ] && cp release/SHA256SUMS "$RELEASES_DIR/deb/pg${pg_ver}/" 2>/dev/null || true
[ -d "$RELEASES_DIR/osx/pg${pg_ver}" ] && cp release/SHA256SUMS "$RELEASES_DIR/osx/pg${pg_ver}/" 2>/dev/null || true
done
fi
echo ""
echo "✅ pgraft packages organized successfully"
echo ""
echo "📂 Package Summary:"
for pg_ver in 13 14 15 16 17 18; do
if [ -d "$RELEASES_DIR/rpm/pg${pg_ver}" ] || [ -d "$RELEASES_DIR/deb/pg${pg_ver}" ] || [ -d "$RELEASES_DIR/osx/pg${pg_ver}" ]; then
echo " PostgreSQL ${pg_ver}:"
echo " RPM: $(ls -1 "$RELEASES_DIR/rpm/pg${pg_ver}" 2>/dev/null | wc -l) files"
echo " DEB: $(ls -1 "$RELEASES_DIR/deb/pg${pg_ver}" 2>/dev/null | wc -l) files"
echo " macOS: $(ls -1 "$RELEASES_DIR/osx/pg${pg_ver}" 2>/dev/null | wc -l) files"
fi
done
- name: Create GitHub Release
if: steps.packages.outputs.has_packages == 'true'
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ github.event.inputs.release_tag }}
name: pgraft ${{ needs.prepare.outputs.version }}
files: |
release/*
body: |
## pgraft ${{ needs.prepare.outputs.version }}-${{ needs.prepare.outputs.release }}
Raft consensus extension for PostgreSQL.
### 📦 Build Artifacts
- **PostgreSQL versions**: 16, 17, 18
- **Platforms**: Ubuntu (.so), Rocky Linux (.so), macOS (.dylib)
### 🚀 Installation
```bash
# Build from source
make PG_CONFIG=/path/to/pg_config
sudo make install PG_CONFIG=/path/to/pg_config
```
### ✨ Features
- Raft consensus protocol (etcd-io/raft)
- Automatic leader election
- Log replication and persistence
- Split-brain prevention
- etcd-compatible SQL views
### 📚 Documentation
- **Quick Start**: https://pgelephant.github.io/pgraft/getting-started/quick-start/
- **Full Docs**: https://pgelephant.github.io/pgraft/
### ✅ Verification
```bash
sha256sum -c SHA256SUMS
```
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}