#!/bin/bash # build-schema-images.sh # Build versioned PostgreSQL images for schema evolution testing # Sprint: SPRINT_20260105_002_005_TEST_cross_cutting # Task: CCUT-008 # # USAGE: # ====== # Build all versions for a module: # ./build-schema-images.sh scanner # # Build specific version: # ./build-schema-images.sh scanner v1.2.0 # # Build all modules: # ./build-schema-images.sh --all set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" REGISTRY="${SCHEMA_REGISTRY:-ghcr.io/stellaops}" POSTGRES_VERSION="${POSTGRES_VERSION:-16}" # Modules with schema evolution support MODULES=("scanner" "concelier" "evidencelocker" "authority" "sbomservice" "policy") usage() { echo "Usage: $0 [version]" echo "" echo "Arguments:" echo " module Module name (scanner, concelier, evidencelocker, authority, sbomservice, policy)" echo " --all Build all modules" echo " version Optional specific version to build (default: all versions)" echo "" echo "Environment variables:" echo " SCHEMA_REGISTRY Container registry (default: ghcr.io/stellaops)" echo " POSTGRES_VERSION PostgreSQL version (default: 16)" echo " PUSH_IMAGES Set to 'true' to push images after build" exit 1 } # Get schema versions from git tags or migration files get_schema_versions() { local module=$1 local versions=() # Check for version tags local tags=$(git tag -l "${module}-schema-v*" 2>/dev/null | sed "s/${module}-schema-//" | sort -V) if [ -n "$tags" ]; then versions=($tags) else # Fall back to migration file count local migration_dir="$REPO_ROOT/docs/db/migrations/${module}" if [ -d "$migration_dir" ]; then local count=$(ls -1 "$migration_dir"/*.sql 2>/dev/null | wc -l) for i in $(seq 1 $count); do versions+=("v1.0.$i") done fi fi # Always include 'latest' versions+=("latest") echo "${versions[@]}" } # Copy schema files to build context prepare_schema_context() { local module=$1 local version=$2 local build_dir="$SCRIPT_DIR/.build/${module}/${version}" mkdir -p "$build_dir/schemas/${module}" mkdir -p "$build_dir/docker-entrypoint-initdb.d" # Copy entrypoint scripts cp "$SCRIPT_DIR/docker-entrypoint-initdb.d/"*.sh "$build_dir/docker-entrypoint-initdb.d/" # Copy base schema local base_schema="$REPO_ROOT/docs/db/schemas/${module}.sql" if [ -f "$base_schema" ]; then cp "$base_schema" "$build_dir/schemas/${module}/base.sql" fi # Copy migrations directory local migrations_dir="$REPO_ROOT/docs/db/migrations/${module}" if [ -d "$migrations_dir" ]; then mkdir -p "$build_dir/schemas/${module}/migrations" cp "$migrations_dir"/*.sql "$build_dir/schemas/${module}/migrations/" 2>/dev/null || true fi echo "$build_dir" } # Build image for module and version build_image() { local module=$1 local version=$2 echo "Building ${module} schema version ${version}..." local build_dir=$(prepare_schema_context "$module" "$version") local image_tag="${REGISTRY}/schema-test:${module}-${version}" local schema_date=$(date -u +%Y-%m-%dT%H:%M:%SZ) # Copy Dockerfile to build context cp "$SCRIPT_DIR/Dockerfile" "$build_dir/" # Build the image docker build \ --build-arg MODULE="$module" \ --build-arg SCHEMA_VERSION="$version" \ --build-arg SCHEMA_DATE="$schema_date" \ --build-arg POSTGRES_VERSION="$POSTGRES_VERSION" \ -t "$image_tag" \ "$build_dir" echo "Built: $image_tag" # Push if requested if [ "$PUSH_IMAGES" = "true" ]; then echo "Pushing: $image_tag" docker push "$image_tag" fi # Cleanup build directory rm -rf "$build_dir" } # Build all versions for a module build_module() { local module=$1 local target_version=$2 echo "========================================" echo "Building schema images for: $module" echo "========================================" if [ -n "$target_version" ]; then build_image "$module" "$target_version" else local versions=$(get_schema_versions "$module") for version in $versions; do build_image "$module" "$version" done fi } # Main if [ $# -lt 1 ]; then usage fi case "$1" in --all) for module in "${MODULES[@]}"; do build_module "$module" "$2" done ;; --help|-h) usage ;; *) if [[ " ${MODULES[*]} " =~ " $1 " ]]; then build_module "$1" "$2" else echo "Error: Unknown module '$1'" echo "Valid modules: ${MODULES[*]}" exit 1 fi ;; esac echo "" echo "Build complete!" echo "To push images, run with PUSH_IMAGES=true"