#!/bin/bash # Exit on any error set -e # Function to display usage information usage() { echo "Usage: $0 [options]" echo " version : Version to push (e.g., v1.2.3, v1.2.3-alpha)" echo " environment : Target environment (staging|production)" echo "" echo "Options:" echo " --services : Specific services to push (default: all EveAI services)" echo " --dry-run : Show what would be done without executing" echo "" echo "Examples:" echo " $0 v1.2.3-alpha staging" echo " $0 v2.0.0 production --services eveai_api,eveai_workers" echo " $0 v1.0.0-beta staging --dry-run" } # Check if required arguments are provided if [ $# -lt 2 ]; then echo "❌ Error: Version and environment are required" usage exit 1 fi VERSION=$1 ENVIRONMENT=$2 shift 2 # Default values SERVICES="" DRY_RUN=false # Parse options while [[ $# -gt 0 ]]; do case $1 in --services) SERVICES="$2" shift 2 ;; --dry-run) DRY_RUN=true shift ;; -*) echo "❌ Unknown option: $1" usage exit 1 ;; *) echo "❌ Unexpected argument: $1" usage exit 1 ;; esac done # Validate environment if [[ "$ENVIRONMENT" != "staging" && "$ENVIRONMENT" != "production" ]]; then echo "❌ Error: Environment must be 'staging' or 'production'" usage exit 1 fi # Validate version format (flexible semantic versioning) if [[ ! "$VERSION" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9\-]+)?$ ]]; then echo "❌ Error: Invalid version format. Expected format: v1.2.3 or v1.2.3-alpha" echo " Examples: v1.0.0, v2.1.3-beta, v1.0.0-rc1" exit 1 fi # Ensure version starts with 'v' if [[ ! "$VERSION" =~ ^v ]]; then VERSION="v$VERSION" fi # Get script directory to find config files SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" CONFIG_FILE="$SCRIPT_DIR/configs/$ENVIRONMENT.conf" # Check if config file exists if [[ ! -f "$CONFIG_FILE" ]]; then echo "❌ Error: Config file not found: $CONFIG_FILE" echo " Please create the config file with Scaleway credentials" exit 1 fi # Load configuration echo "📋 Loading configuration from: $CONFIG_FILE" source "$CONFIG_FILE" # Validate required config variables if [[ -z "$SCALEWAY_REGISTRY" || -z "$SCALEWAY_API_KEY" ]]; then echo "❌ Error: Missing required configuration in $CONFIG_FILE" echo " Required: SCALEWAY_REGISTRY, SCALEWAY_API_KEY" exit 1 fi # Local registry configuration LOCAL_REGISTRY="registry.ask-eve-ai-local.com" ACCOUNT="josakola" # Check if podman is available if ! command -v podman &> /dev/null; then echo "❌ Error: podman not found" exit 1 fi # Check if yq is available if ! command -v yq &> /dev/null; then echo "❌ Error: yq not found (required for parsing compose file)" exit 1 fi # Check if compose file exists COMPOSE_FILE="../docker/compose_dev.yaml" if [[ ! -f "$COMPOSE_FILE" ]]; then echo "❌ Error: Compose file '$COMPOSE_FILE' not found" exit 1 fi echo "🚀 EveAI Scaleway Push Script" echo "📦 Version: $VERSION" echo "🌍 Environment: $ENVIRONMENT" echo "🏪 Local Registry: $LOCAL_REGISTRY" echo "☁️ Scaleway Registry: $SCALEWAY_REGISTRY" echo "👤 Account: $ACCOUNT" # Get services to process if [[ -n "$SERVICES" ]]; then # Convert comma-separated list to array IFS=',' read -ra SERVICE_ARRAY <<< "$SERVICES" else # Get all EveAI services (excluding nginx as per requirements) SERVICE_ARRAY=() while IFS= read -r line; do SERVICE_ARRAY+=("$line") done < <(yq e '.services | keys | .[]' "$COMPOSE_FILE" | grep -E '^eveai_') fi echo "🔍 Services to process: ${SERVICE_ARRAY[*]}" # Function to check if image exists locally check_local_image_exists() { local image_name="$1" if podman image exists "$image_name" 2>/dev/null; then return 0 else return 1 fi } # Function to authenticate with Scaleway registry authenticate_scaleway() { echo "🔐 Authenticating with Scaleway registry..." if [[ "$DRY_RUN" == true ]]; then echo " 🔍 [DRY RUN] Would authenticate with Scaleway registry" return 0 fi # Extract registry hostname from full registry URL REGISTRY_HOST=$(echo "$SCALEWAY_REGISTRY" | cut -d'/' -f1) # Login to Scaleway registry using API key if ! echo "$SCALEWAY_API_KEY" | podman login --username nologin --password-stdin "$REGISTRY_HOST"; then echo " ❌ Failed to authenticate with Scaleway registry" echo " 💡 Check your API key in $CONFIG_FILE" return 1 fi echo " ✅ Successfully authenticated with Scaleway registry" return 0 } # Authenticate with Scaleway if ! authenticate_scaleway; then exit 1 fi # Process each service PROCESSED_SERVICES=() FAILED_SERVICES=() for SERVICE in "${SERVICE_ARRAY[@]}"; do echo "" echo "🔄 Processing service: $SERVICE" # Check if service exists in compose file if ! yq e ".services.$SERVICE" "$COMPOSE_FILE" | grep -q "image:"; then echo "⚠️ Warning: Service '$SERVICE' not found in $COMPOSE_FILE, skipping" continue fi # Construct image names LOCAL_VERSION_IMAGE="$LOCAL_REGISTRY/$ACCOUNT/$SERVICE:$VERSION" SCALEWAY_VERSION_IMAGE="$SCALEWAY_REGISTRY/$ACCOUNT/$SERVICE:$VERSION" echo " 📥 Source: $LOCAL_VERSION_IMAGE" echo " 📤 Target: $SCALEWAY_VERSION_IMAGE" if [[ "$DRY_RUN" == true ]]; then echo " 🔍 [DRY RUN] Would push $LOCAL_VERSION_IMAGE to $SCALEWAY_VERSION_IMAGE" PROCESSED_SERVICES+=("$SERVICE") continue fi # Check if local version image exists if ! check_local_image_exists "$LOCAL_VERSION_IMAGE"; then echo " ❌ Local version image not found: $LOCAL_VERSION_IMAGE" echo " 💡 Run tag_registry_version.sh first to create version tags" FAILED_SERVICES+=("$SERVICE") continue fi # Pull local version image to ensure we have it echo " 📥 Pulling local version image..." if ! podman pull "$LOCAL_VERSION_IMAGE"; then echo " ❌ Failed to pull $LOCAL_VERSION_IMAGE" FAILED_SERVICES+=("$SERVICE") continue fi # Tag for Scaleway registry (direct push with same version tag) echo " 🏷️ Tagging for Scaleway registry..." if ! podman tag "$LOCAL_VERSION_IMAGE" "$SCALEWAY_VERSION_IMAGE"; then echo " ❌ Failed to tag $LOCAL_VERSION_IMAGE as $SCALEWAY_VERSION_IMAGE" FAILED_SERVICES+=("$SERVICE") continue fi # Push to Scaleway registry echo " 📤 Pushing to Scaleway registry..." if ! podman push "$SCALEWAY_VERSION_IMAGE"; then echo " ❌ Failed to push $SCALEWAY_VERSION_IMAGE" FAILED_SERVICES+=("$SERVICE") continue fi # Clean up local Scaleway tag echo " 🧹 Cleaning up local Scaleway tag..." podman rmi "$SCALEWAY_VERSION_IMAGE" 2>/dev/null || true echo " ✅ Successfully pushed $SERVICE version $VERSION to Scaleway" PROCESSED_SERVICES+=("$SERVICE") done # Summary echo "" echo "📊 Summary:" echo "✅ Successfully processed: ${#PROCESSED_SERVICES[@]} services" if [[ ${#PROCESSED_SERVICES[@]} -gt 0 ]]; then printf " - %s\n" "${PROCESSED_SERVICES[@]}" fi if [[ ${#FAILED_SERVICES[@]} -gt 0 ]]; then echo "❌ Failed: ${#FAILED_SERVICES[@]} services" printf " - %s\n" "${FAILED_SERVICES[@]}" fi if [[ "$DRY_RUN" == true ]]; then echo "🔍 This was a dry run - no actual changes were made" fi echo "" if [[ ${#FAILED_SERVICES[@]} -eq 0 ]]; then echo "🎉 All services successfully pushed to Scaleway $ENVIRONMENT!" echo "☁️ Images are available in Scaleway registry: $SCALEWAY_REGISTRY/$ACCOUNT/[service]:$VERSION" else echo "⚠️ Some services failed to process. Check the errors above." exit 1 fi echo "🕐 Finished at $(date +"%d/%m/%Y %H:%M:%S")"