CI/CD Documentation
Documents a GitHub Actions CI pipeline that builds and tests a PostgreSQL extension across multiple versions using containerized PostgreSQL.
What this file does
Documents a GitHub Actions CI pipeline that builds and tests a PostgreSQL extension across multiple versions using containerized PostgreSQL.
When to use it
- Setting up CI for a PostgreSQL extension that must support multiple PG versions
- Learning how to test a PG extension inside Docker containers from GitHub Actions
- Understanding a matrix build with Ubuntu versions and PostgreSQL versions
- Adding local Docker-based testing for a PG extension project
Assumes this stack
CI/CD Documentation
Overview
The pg_background CI pipeline uses GitHub Actions with containerized PostgreSQL to ensure consistent, deterministic testing across multiple PostgreSQL versions (14-18). The workflow builds the extension on Ubuntu runners with proper development headers and copies the built artifacts into PostgreSQL Docker containers for testing.
Quick Start
Local Testing with Docker
The easiest way to run tests locally is using the provided test-local.sh script:
# Test with default PostgreSQL version (17)
./test-local.sh
# Test with a specific version
./test-local.sh 14
./test-local.sh 15
./test-local.sh 16
./test-local.sh 17
./test-local.sh 18
# Test all supported versions (14-18)
./test-local.sh all
Requirements: Docker must be installed and running. No local PostgreSQL installation required.
CI Workflow Architecture
Jobs
| Job | Purpose | Runs On | Timeout |
|---|---|---|---|
| test | Build and test against PostgreSQL matrix | ubuntu-22.04, ubuntu-24.04 | 15 min |
| test-summary | Aggregate test results | ubuntu-latest | - |
| lint | Static analysis (cppcheck, clang-format) | ubuntu-latest | 10 min |
| security | CodeQL security scanning | ubuntu-latest | 20 min |
Test Matrix
The test job runs against all combinations:
| Ubuntu Version | PostgreSQL Versions |
|---|---|
| 22.04 | 14, 15, 16, 17, 18 |
| 24.04 | 14, 15, 16, 17, 18 |
Total: 10 parallel test jobs
Workflow Triggers
- Push:
master,main,develop,v1.*,improvements/*branches - Tags:
v*(releases) - Pull Requests: To
masterormain - Manual: Via
workflow_dispatch
Concurrency Control
The workflow automatically cancels in-progress runs when new commits are pushed to the same branch, saving CI minutes and providing faster feedback.
Build and Test Flow
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Start Docker │────▶│ Build on Runner │────▶│ Copy to Docker │
│ PostgreSQL │ │ (with dev hdrs) │ │ Container │
└─────────────────┘ └──────────────────┘ └────────┬────────┘
│
▼
┌─────────────────┐
│ Run Regression │
│ Tests │
└─────────────────┘
- Start Container: PostgreSQL container started with
docker run - Build on Runner: Extension built with PGDG development headers
- Copy Artifacts: Built
.soand SQL files copied into running container - Run Tests: Regression tests connect to containerized PostgreSQL
Key Features
- APT Package Caching: Faster subsequent runs
- Parallel Matrix Execution: All 10 test combinations run simultaneously
- Artifact Upload on Failure: Regression diffs available for debugging
- clang/llvm Symlink Handling: Automatic compatibility for PGXS requirements
Extension Features Tested
The regression tests verify all pg_background v1.8 functionality:
- v1 API:
pg_background_launch(),pg_background_result(),pg_background_detach() - v2 API:
pg_background_launch_v2(),pg_background_detach_v2(),pg_background_cancel_v2() - Wait Functions:
pg_background_wait_v2(),pg_background_wait_v2_timeout() - Progress Reporting:
pg_background_progress(),pg_background_get_progress_v2() - Statistics:
pg_background_stats_v2(),pg_background_list_v2() - GUC Settings:
pg_background.max_workers,pg_background.default_queue_size,pg_background.worker_timeout
Manual Local Testing
If you prefer not to use test-local.sh, follow these steps:
1. Start PostgreSQL Container
PG_VERSION=17
docker run --name postgres-test -d \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_USER=postgres \
-e POSTGRES_DB=postgres \
-p 5432:5432 \
postgres:${PG_VERSION}
# Wait for PostgreSQL to be ready
for i in {1..30}; do
if docker exec postgres-test pg_isready -U postgres >/dev/null 2>&1; then
echo "PostgreSQL is ready"
break
fi
echo "Waiting... ($i/30)"
sleep 2
done
2. Install Build Dependencies
# Add PostgreSQL APT repository
sudo apt-get update
sudo apt-get install -y ca-certificates wget gnupg lsb-release build-essential libkrb5-dev
sudo install -d -m 0755 /usr/share/keyrings
wget -qO- https://www.postgresql.org/media/keys/ACCC4CF8.asc \
| sudo gpg --dearmor -o /usr/share/keyrings/postgresql.gpg
echo "deb [signed-by=/usr/share/keyrings/postgresql.gpg] \
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
sudo apt-get install -y \
postgresql-client-${PG_VERSION} \
postgresql-server-dev-${PG_VERSION}
3. Build the Extension
export PG_CONFIG=/usr/lib/postgresql/${PG_VERSION}/bin/pg_config
make clean && make
4. Copy to Container
PKGLIBDIR=$($PG_CONFIG --pkglibdir)
SHAREDIR=$($PG_CONFIG --sharedir)
docker exec postgres-test mkdir -p "$PKGLIBDIR" "$SHAREDIR/extension"
docker cp pg_background.so postgres-test:$PKGLIBDIR/
docker cp pg_background.control postgres-test:$SHAREDIR/extension/
for f in pg_background--*.sql; do docker cp "$f" postgres-test:$SHAREDIR/extension/; done
5. Run Tests
export PGHOST=127.0.0.1 PGPORT=5432 PGUSER=postgres PGPASSWORD=postgres PGDATABASE=postgres
export PATH=/usr/lib/postgresql/${PG_VERSION}/bin:$PATH
make installcheck REGRESS_OPTS+=" --host=$PGHOST --port=$PGPORT --user=$PGUSER"
6. Cleanup
docker stop postgres-test && docker rm postgres-test
Troubleshooting
Build Fails with "Cannot find postgres.h"
Ensure PG_CONFIG points to the correct pg_config:
export PG_CONFIG=/usr/lib/postgresql/${PG_VERSION}/bin/pg_config
$PG_CONFIG --includedir-server # Should show header directory
make clean && make
Build Fails with clang-19 or llvm-lto Not Found
PGXS may expect specific clang/llvm versions. Create symlinks:
sudo ln -sf /usr/bin/clang /usr/bin/clang-19
LLVM_VER=$(ls -d /usr/lib/llvm-* 2>/dev/null | sort -V | tail -1 | sed 's|.*/llvm-||')
sudo mkdir -p /usr/lib/llvm-19/bin
sudo ln -sf /usr/lib/llvm-${LLVM_VER}/bin/llvm-lto /usr/lib/llvm-19/bin/llvm-lto
Tests Fail with Connection Errors
Verify container is running:
docker ps
docker exec postgres-test pg_isready -U postgres
psql -h 127.0.0.1 -p 5432 -U postgres -d postgres -c "SELECT version();"
Extension Not Found After Copying
Verify paths match pg_config:
docker exec postgres-test ls -la /usr/lib/postgresql/${PG_VERSION}/lib/pg_background.so
docker exec postgres-test ls -la /usr/share/postgresql/${PG_VERSION}/extension/pg_background.control
Regression Test Diffs
Check the diff output:
cat regression.diffs
cat regression.out
ls results/
CI Environment Variables
| Variable | Description | Example |
|---|---|---|
PG_CONFIG | Path to pg_config binary | /usr/lib/postgresql/17/bin/pg_config |
PGHOST | PostgreSQL host | 127.0.0.1 |
PGPORT | PostgreSQL port | 5432 |
PGUSER | Database user | postgres |
PGPASSWORD | Database password | postgres |
PGDATABASE | Database name | postgres |
DEFAULT_PG_VERSION | Default PG version for lint/security | 17 |
Contributing
When modifying CI:
- Test changes locally using
./test-local.shfirst - Consider all matrix combinations (10 total)
- Update this documentation if workflow changes
- Keep YAML readable; complex logic goes in step scripts
References
What's inside
7 sections: overview, quick start, workflow architecture, build flow, features tested, manual steps, troubleshooting
Change this for your project
- Replace
pg_backgroundwith your extension name in file paths and commands - Replace
vibhorkum/pg_backgroundwith your repository name in workflow triggers - Replace
PG_VERSION=17andDEFAULT_PG_VERSION=17with your default version - Replace
pg_background--*.sqlwith your extension's SQL files pattern
Where it goes
Keep it in your repository where the agent or team that needs it will read it.
Worth borrowing
- Copying built artifacts into a running Docker container for testing instead of installing PG on the runner
- Using a shell script (
test-local.sh) to replicate CI steps locally for fast iteration - Caching APT packages to speed up repeated CI runs
Related Documents
SVI 2.0
Documents the SVI LoRA family for WanVideo I2V, covering version history, usage patterns, known limitations, and community workflows.
第一章 模型预处理
> 译者:[muxuezi](https://muxuezi.github.io/posts/1-premodel-workflow.html)
TVM: An Automated End-to-End Optimizing Compiler for Deep Learning
Describes TVM, a compiler that optimizes deep learning models for diverse hardware back-ends using graph-level and operator-level transformations.
Content Workflow
Defines a 6-stage content production pipeline with automated quality scoring and self-healing gates that enforce an 8.0 minimum score across four dimensions.