Files
git.stella-ops.org/devops/docker/schema-versions/build-schema-images.sh
StellaOps Bot 37e11918e0 save progress
2026-01-06 09:42:20 +02:00

180 lines
4.9 KiB
Bash

#!/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 <module|--all> [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"