#!/bin/bash set -euo pipefail # Manage deployment releases # Usage: ./manage-releases.sh REPO_PROJECT_PATH COMMAND [ARGS] if [ $# -lt 2 ]; then echo "Error: Invalid number of arguments" echo "Usage: $0 REPO_PROJECT_PATH COMMAND [ARGS]" echo "Commands:" echo " list - List all releases" echo " current - Show current release" echo " rollback VERSION - Rollback to specific version" echo " cleanup [KEEP] - Clean up old releases (default: keep 5)" exit 1 fi REPO_PROJECT_PATH="$1" COMMAND="$2" CURRENT_LINK_PATH="${REPO_PROJECT_PATH}/current" RELEASES_PATH="${REPO_PROJECT_PATH}/releases" case "$COMMAND" in list) echo "📋 Available releases:" if [ -d "$RELEASES_PATH" ]; then for release in $(ls -dt "${RELEASES_PATH}"/*/); do version=$(basename "$release") status="" # Check if it's current if [ -L "$CURRENT_LINK_PATH" ] && [ "$(readlink -f "$CURRENT_LINK_PATH")" = "$(realpath "$release")" ]; then status=" [CURRENT]" fi # Check if it failed if [ -f "${release}/.failed" ]; then status="${status} [FAILED]" fi echo " - ${version}${status}" done else echo "No releases found" fi ;; current) if [ -L "$CURRENT_LINK_PATH" ]; then current_version=$(basename "$(readlink -f "$CURRENT_LINK_PATH")") echo "📌 Current version: ${current_version}" else echo "❌ No current deployment found" fi ;; rollback) if [ $# -lt 3 ]; then echo "Error: VERSION required for rollback" exit 1 fi TARGET_VERSION="$3" TARGET_PATH="${RELEASES_PATH}/${TARGET_VERSION}" if [ ! -d "$TARGET_PATH" ]; then echo "Error: Version ${TARGET_VERSION} not found" exit 1 fi echo "🔄 Rolling back to version: ${TARGET_VERSION}" # Read environment from target version if [ -f "${TARGET_PATH}/.deployment_env" ]; then PROD=$(cat "${TARGET_PATH}/.deployment_env") else echo "Warning: Could not determine environment, assuming staging" PROD="false" fi # Stop current containers if [ -L "$CURRENT_LINK_PATH" ] && [ -d "$CURRENT_LINK_PATH" ]; then cd "$CURRENT_LINK_PATH" docker compose -f docker-compose_web.yml down || true [ "$PROD" = "false" ] && docker compose -f docker-compose_staging.yml down || true docker compose -f docker-compose_core.yml down || true fi # Update symlink ln -sfn "$TARGET_PATH" "$CURRENT_LINK_PATH" # Start containers cd "$CURRENT_LINK_PATH" docker compose -f docker-compose_core.yml up -d --no-build if [ "$PROD" = "true" ]; then docker compose -f docker-compose_web.yml up -d --no-build else docker compose -f docker-compose_web.yml -f docker-compose_staging.yml up -d --no-build fi echo "✅ Rollback completed" ;; cleanup) KEEP_COUNT="${3:-5}" echo "🗑️ Cleaning up old releases (keeping last ${KEEP_COUNT})" if [ -d "$RELEASES_PATH" ]; then cd "$RELEASES_PATH" ls -dt */ 2>/dev/null | tail -n +$((KEEP_COUNT + 1)) | xargs -r rm -rf || true echo "✅ Cleanup completed" else echo "No releases directory found" fi ;; *) echo "Error: Unknown command: $COMMAND" exit 1 ;; esac