| doc_id | DBS-GUID-009 |
|---|---|
| doc_title | CI/CD Guide for database_system |
| doc_version | 1.0.0 |
| doc_date | 2026-04-04 |
| doc_status | Released |
| project | database_system |
| category | GUID |
SSOT: This document is the single source of truth for CI/CD Guide for database_system.
Version: 0.1.0 Last Updated: 2025-11-11 Status: Stable Audience: Contributors, Maintainers
This guide explains the Continuous Integration and Continuous Deployment (CI/CD) pipelines for database_system. Understanding these workflows will help you:
- Run checks locally before pushing
- Interpret CI failures
- Add new tests to the pipeline
- Debug platform-specific issues
- CI/CD Pipeline Overview
- GitHub Actions Workflows
- Running Checks Locally
- Understanding CI Failures
- Adding New Tests
- Performance Benchmarks
- Troubleshooting
┌─────────────────────────────────────────────────────────────┐
│ Push to branch / Open Pull Request │
└──────────────────┬──────────────────────────────────────────┘
│
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
┌────────┐ ┌────────────┐ ┌──────────┐
│ Main │ │ Sanitizers │ │ Coverage │
│ CI │ │ (TSan, │ │ │
│ │ │ ASan, │ │ │
│ │ │ UBSan) │ │ │
└────┬───┘ └──────┬─────┘ └────┬─────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────┐
│ Static Analysis │
│ - Clang-Tidy │
│ - Cppcheck │
└────────────┬────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Security Scan │
│ - Dependency vulnerabilities │
└────────────┬────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Integration Tests │
│ - Backend-specific tests │
└────────────┬────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Benchmarks │
│ - Performance regression tests │
└────────────┬────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Documentation Build (Doxygen) │
└─────────────────────────────────────┘
| Workflow | Trigger | Runs On |
|---|---|---|
| Main CI | Push to main, phase-* branches; All PRs | Every commit |
| Sanitizers | Push to main, phase-* branches; All PRs | Every commit |
| Static Analysis | Push to main; PRs to main | Every commit |
| Security Scan | Push to main; Weekly schedule | Push + Weekly |
| Integration Tests | PRs to main (on-demand) | Manual/PR label |
| Benchmarks | Push to main; Monthly schedule | Push + Monthly |
| Coverage | PRs to main | PRs only |
| Doxygen | Push to main | On main branch |
Purpose: Build and test across multiple platforms and compilers
Matrix:
- Platforms: Ubuntu 22.04, macOS 13, Windows 2022
- Compilers: GCC, Clang, MSVC
- Build Type: Debug
- Configuration: Standalone (no external dependencies)
Steps:
- Checkout code with submodules
- Install dependencies (CMake, Ninja, GoogleTest)
- Configure CMake with backend flags
- Build with parallel compilation
- Run unit tests (timeout: 30s per test)
- Upload logs on failure
Key Configuration:
cmake -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Debug \
-DBUILD_WITH_COMMON_SYSTEM=OFF \
-DUSE_UNIT_TEST=ON \
-DBUILD_DATABASE_SAMPLES=ON \
-DDATABASE_BUILD_INTEGRATION_TESTS=OFF \
-DUSE_POSTGRESQL=OFFCurrent Status: ✅ Passing (22/23 tests)
Purpose: Detect memory issues, data races, and undefined behavior
Sanitizers Run:
-
ThreadSanitizer (TSan)
- Detects data races
- Flags:
-fsanitize=thread -g -O1 - Environment:
TSAN_OPTIONS=second_deadlock_stack=1
-
AddressSanitizer (ASan)
- Detects memory errors (use-after-free, buffer overflows)
- Flags:
-fsanitize=address -fno-omit-frame-pointer -g -O1 - Environment:
ASAN_OPTIONS=detect_leaks=1:strict_string_checks=1
-
UndefinedBehaviorSanitizer (UBSan)
- Detects undefined behavior
- Flags:
-fsanitize=undefined -fno-omit-frame-pointer -g -O1 - Environment:
UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=0
Status:
Purpose: Catch potential bugs and style issues
Tools:
- Clang-Tidy: Modern C++ linter
- Cppcheck: Static code analyzer
- Include-what-you-use: Header dependency checker
Checks:
- Modernize recommendations
- Performance issues
- Readability improvements
- Bug-prone patterns
- Security vulnerabilities
Purpose: Identify vulnerable dependencies
Scans:
- vcpkg dependencies
- System libraries
- Transitive dependencies
Schedule: Weekly + on push to main
Purpose: Test with real database backends
Backends Tested:
- PostgreSQL 15
- SQLite 3
- MongoDB 6.0
- Redis 7.0
Setup: Uses Docker containers for database services
Trigger: Manual or on PR with label run-integration-tests
Purpose: Track performance over time
Metrics:
- Connection pool performance
- Query latency (simple, complex, joins)
- Bulk insert throughput
- Transaction overhead
- Cache hit rates
Baseline: See PERFORMANCE_BENCHMARKS.md
Schedule: On push to main + monthly
Purpose: Measure test coverage
Tool: lcov + gcov
Target: >80% coverage for new code
Reports: Uploaded to Codecov (if configured)
Purpose: Generate API documentation
Output: HTML documentation from Doxygen comments
Deployment: GitHub Pages (if enabled)
# Install tools
sudo apt-get install cmake ninja-build clang clang-tidy cppcheck lcov
# Install compilers
sudo apt-get install g++-11 clang-15
# Install Google Test
sudo apt-get install libgtest-dev libgmock-devReplicate the CI build locally:
# Configure (same as CI)
cmake -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Debug \
-DBUILD_WITH_COMMON_SYSTEM=OFF \
-DUSE_UNIT_TEST=ON \
-DBUILD_DATABASE_SAMPLES=ON \
-DDATABASE_BUILD_INTEGRATION_TESTS=OFF \
-DUSE_POSTGRESQL=OFF
# Build
cmake --build build --config Debug --parallel
# Test
cd build
ctest -C Debug --output-on-failure --timeout 30ThreadSanitizer:
cmake -B build-tsan -G Ninja \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_CXX_FLAGS="-fsanitize=thread -g -O1" \
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=thread" \
-DUSE_UNIT_TEST=ON \
-DUSE_POSTGRESQL=OFF
cmake --build build-tsan
cd build-tsan
export TSAN_OPTIONS=second_deadlock_stack=1
ctest --output-on-failureAddressSanitizer:
cmake -B build-asan -G Ninja \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_CXX_FLAGS="-fsanitize=address -fno-omit-frame-pointer -g -O1" \
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address" \
-DUSE_UNIT_TEST=ON \
-DUSE_POSTGRESQL=OFF
cmake --build build-asan
cd build-asan
export ASAN_OPTIONS=detect_leaks=1:strict_string_checks=1
ctest --output-on-failureUndefinedBehaviorSanitizer:
cmake -B build-ubsan -G Ninja \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_CXX_FLAGS="-fsanitize=undefined -fno-omit-frame-pointer -g -O1" \
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=undefined" \
-DUSE_UNIT_TEST=ON \
-DUSE_POSTGRESQL=OFF
cmake --build build-ubsan
cd build-ubsan
export UBSAN_OPTIONS=print_stacktrace=1
ctest --output-on-failureClang-Tidy:
# Generate compile_commands.json
cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
# Run clang-tidy
clang-tidy -p build database/**/*.cpp -- -std=c++17Cppcheck:
cppcheck --enable=all --std=c++17 \
--suppress=missingIncludeSystem \
-I database/include \
database/# Configure with coverage flags
cmake -B build-coverage -G Ninja \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS="--coverage -g -O0" \
-DCMAKE_EXE_LINKER_FLAGS="--coverage" \
-DUSE_UNIT_TEST=ON \
-DUSE_POSTGRESQL=OFF
# Build and test
cmake --build build-coverage
cd build-coverage
ctest
# Generate coverage report
lcov --capture --directory . --output-file coverage.info
lcov --remove coverage.info '/usr/*' '*/tests/*' --output-file coverage_filtered.info
genhtml coverage_filtered.info --output-directory coverage_report
# View report
open coverage_report/index.html # macOS
xdg-open coverage_report/index.html # LinuxSetup databases with Docker:
# PostgreSQL
docker run -d --name postgres-test \
-e POSTGRES_PASSWORD=test \
-p 5432:5432 postgres:15
# MongoDB
docker run -d --name mongo-test \
-p 27017:27017 mongo:6.0
# Redis
docker run -d --name redis-test \
-p 6379:6379 redis:7.0Build and test:
cmake -B build -G Ninja \
-DDATABASE_BUILD_INTEGRATION_TESTS=ON \
-DUSE_POSTGRESQL=ON \
-DUSE_SQLITE=ON \
-DUSE_MONGODB=ON \
-DUSE_REDIS=ON
cmake --build build
cd build
ctest -R integration --output-on-failureCleanup:
docker stop postgres-test mongo-test redis-test
docker rm postgres-test mongo-test redis-testSymptom: Compilation errors
Example:
error: 'std::optional' does not name a type
Diagnosis:
- Check compiler version (C++17 required)
- Verify include paths
- Check for missing dependencies
Solution:
# Check compiler version
g++ --version # Should be 7.0+
clang++ --version # Should be 5.0+
# Update compiler if needed
sudo apt-get install g++-11Symptom: CTest reports test failures
Example:
Test #5: connection_pool_test ...................***Failed 0.12 sec
Diagnosis:
- Check test output:
ctest --output-on-failure --rerun-failed - Run specific test:
./build/tests/connection_pool_test - Use debugger:
gdb ./build/tests/connection_pool_test
Common causes:
- Backend not available
- Port conflicts
- Timeout issues
- Race conditions (check with TSan)
Symptom: TSan/ASan/UBSan reports issues
ThreadSanitizer Example:
WARNING: ThreadSanitizer: data race (pid=12345)
Write of size 8 at 0x7b0400000000 by thread T1:
#0 connection_pool::acquire() connection_pool.cpp:123
Diagnosis:
- Identify the data race location
- Check for missing synchronization
- Verify lock acquisition order
Solution:
- Add mutex protection
- Use atomic operations
- Apply proper lock ordering
AddressSanitizer Example:
ERROR: AddressSanitizer: heap-use-after-free
Diagnosis:
- Check object lifetime
- Verify shared_ptr usage
- Look for dangling pointers
Clang-Tidy Example:
warning: use nullptr instead of NULL [modernize-use-nullptr]
Solution:
// Before
void* ptr = NULL;
// After
void* ptr = nullptr;Symptom: Coverage drops below threshold
Solution:
- Add tests for new code
- Test error paths
- Test edge cases
- Create test file in
tests/:
// tests/my_feature_test.cpp
#include <gtest/gtest.h>
#include <database/my_feature.h>
TEST(MyFeature, BasicUsage) {
MyFeature feature;
EXPECT_TRUE(feature.works());
}
TEST(MyFeature, ErrorHandling) {
MyFeature feature;
EXPECT_THROW(feature.invalid_operation(), std::runtime_error);
}- Add to
tests/CMakeLists.txt:
add_executable(my_feature_test my_feature_test.cpp)
target_link_libraries(my_feature_test database_system GTest::gtest_main)
gtest_discover_tests(my_feature_test)- Run test:
cmake --build build
cd build
ctest -R my_feature_test --output-on-failure- Create test in
integration_tests/:
// integration_tests/postgres_feature_test.cpp
#include <gtest/gtest.h>
#include <database/unified_database_system.h>
TEST(PostgresIntegration, MyFeature) {
auto db = create_unified_database("postgresql://localhost/testdb");
// Test with real database
}- Add to
integration_tests/CMakeLists.txt:
if(USE_POSTGRESQL)
add_executable(postgres_feature_test postgres_feature_test.cpp)
target_link_libraries(postgres_feature_test database_system GTest::gtest_main)
gtest_discover_tests(postgres_feature_test)
endif()- Run integration test:
# Start PostgreSQL (Docker)
docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=test postgres:15
# Run test
cmake --build build
cd build
ctest -R postgres_feature_test --output-on-failure- Create benchmark in
benchmarks/:
// benchmarks/my_feature_benchmark.cpp
#include <benchmark/benchmark.h>
#include <database/my_feature.h>
static void BM_MyFeature(benchmark::State& state) {
MyFeature feature;
for (auto _ : state) {
feature.operation();
}
}
BENCHMARK(BM_MyFeature);
BENCHMARK_MAIN();- Add to
benchmarks/CMakeLists.txt:
add_executable(my_feature_benchmark my_feature_benchmark.cpp)
target_link_libraries(my_feature_benchmark database_system benchmark::benchmark)- Run benchmark:
./build/benchmarks/my_feature_benchmark --benchmark_format=json > results.json# Build benchmarks
cmake -B build -DBUILD_BENCHMARKS=ON -DCMAKE_BUILD_TYPE=Release
cmake --build build
# Run all benchmarks
cd build/benchmarks
./run_all_benchmarks.sh
# Run specific benchmark
./connection_pool_benchmark
./query_performance_benchmarkExample output:
-----------------------------------------------------------------
Benchmark Time CPU Iterations
-----------------------------------------------------------------
BM_ConnectionPool/Acquire 0.12 ms 0.12 ms 5698
BM_SimpleQuery/Select 1.20 ms 1.15 ms 608
BM_BulkInsert/1000_rows 45.00 ms 44.50 ms 16
Comparison with baseline:
- See BASELINE.md for expected values
- Regression threshold: >10% slowdown triggers investigation
Possible causes:
-
Platform differences:
- Test on multiple OSes locally
- Use Docker for consistent environment
-
Timing issues:
- Tests may be timing-sensitive
- GitHub runners may be slower
- Add retries or longer timeouts
-
Network dependencies:
- CI may have network restrictions
- Mock external services
Symptom: Test killed after 30s
Solution:
# Increase timeout in ctest
ctest --timeout 60
# Or fix slow test
# - Reduce test data size
# - Mock expensive operations
# - Split into smaller testsThreadSanitizer suppressions:
# Create tsan.supp
cat > tsan.supp <<EOF
race:third_party_library
EOF
# Use suppression file
export TSAN_OPTIONS="suppressions=tsan.supp"Port conflicts:
# Check port usage
lsof -i :5432
sudo netstat -tulpn | grep 5432
# Use different port
docker run -p 5433:5432 postgres:15- Run tests locally before pushing
- Run sanitizers on new code
- Check static analysis warnings
- Ensure coverage >80% for new code
- Test on multiple platforms if possible
- Write clear commit messages for CI logs
- Review CI logs for all PRs
- Investigate flaky tests immediately
- Update baselines after performance improvements
- Monitor sanitizer reports weekly
- Review security scans weekly
- Keep dependencies updated
- Contributing Guide - General contribution guidelines
- Build Guide - Detailed build instructions
- Performance Benchmarks - Performance baselines
- Troubleshooting - General troubleshooting
For CI/CD issues:
- GitHub Issues: database_system/issues
- CI Logs: Check GitHub Actions
- Maintainers: See CONTRIBUTING.md
Document Maintenance:
- Review quarterly
- Update after CI changes
- Keep baseline metrics current
Last Review: 2025-11-11 Next Review: 2026-02-11