Files
recipe-app/deploy.sh
T
Nils-Johan Gynther 0ebb39150f
Test Suite / backend-pr-quick (push) Has been skipped
Test Suite / quick-import-pr-quick (push) Has been skipped
Test Suite / backend-full (push) Successful in 2m11s
Test Suite / flutter-quality (push) Failing after 1m20s
ci(deploy): add migration control and deployment improvements
- Add SKIP_MIGRATION environment variable to control automatic Prisma migrations in backend
- Update Dockerfile to conditionally run migrations based on SKIP_MIGRATION flag
- Enhance deploy.sh with:
  - Better error handling using set -euo pipefail
  - New --skip-migration flag to bypass automatic migration startup
  - Improved documentation and help text
  - New helper functions for waiting on services and database
  - Better status reporting for migration results
- Update compose.yml to include SKIP_MIGRATION environment variable
2026-05-21 14:13:54 +02:00

231 lines
8.4 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# deploy.sh Bygg och starta om recipe-app
# Kör från: /opt/containers/recipe-app/
# Kräver: .env-fil i samma mapp
#
# Användning:
# ./deploy.sh bygg allt (backend + flutter + importer)
# ./deploy.sh --backend bygg bara backend (snabbast, ~2-3 min)
# ./deploy.sh --flutter bygg bara flutter web-app
# ./deploy.sh --importer bygg bara importer-microservice
# ./deploy.sh --seed kör full seed på databasen (opt-in)
# ./deploy.sh --migrate kör Prisma-migrationer explicit (opt-in)
# ./deploy.sh --skip-migration hoppa över automatisk startup-migrering i recipe-api
# ./deploy.sh --clean-database kör underhålls-SQL som rensar data men behåller kategorier
# ./deploy.sh --pull-always kontrollera uppdateringar för basimages
# ./deploy.sh --backend --seed kombinera flaggor fritt (git pull körs alltid)
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
START_TS="$(date +%s)"
# ── Flaggor ──────────────────────────────────────────────────────────────────
BUILD_BACKEND=false
BUILD_FLUTTER=false
BUILD_IMPORTER=false
RUN_SEED=false
RUN_MIGRATE=false
RUN_CLEAN_DATABASE=false
SKIP_MIGRATION=false
PULL_IMAGES=false # --pull=false är standard (snabbt)
BUILD_ALL=true # om inga specifika tjänster anges, bygg allt
# ── Hjälpfunktioner ───────────────────────────────────────────────────────────
info() { echo "[INFO] $*"; }
warn() { echo "[WARN] $*"; }
fatal() { echo "[ERROR] $*"; exit 1; }
require_cmd() {
command -v "$1" >/dev/null 2>&1 || fatal "Kommando saknas: $1"
}
read_env_value() {
local key="$1"
local line
line=$(grep -E "^${key}=" .env | tail -n 1 || true)
line="${line#*=}"
line="${line%\"}"
line="${line#\"}"
line="${line%\'}"
line="${line#\'}"
printf '%s' "$line"
}
wait_for_backend_prisma() {
info "Väntar på att backend är redo för Prisma-kommandon..."
for i in $(seq 1 30); do
if docker exec recipe-api sh -lc "test -f /app/prisma/schema.prisma" >/dev/null 2>&1; then
return 0
fi
info " ...försök $i/30"
sleep 2
done
return 1
}
wait_for_db() {
local root_password="$1"
info "Väntar på att databasen är redo..."
for i in $(seq 1 30); do
if docker exec recipe-db mariadb-admin ping -h 127.0.0.1 -uroot -p"$root_password" --silent 2>/dev/null; then
return 0
fi
info " ...försök $i/30"
sleep 2
done
return 1
}
run_prisma_migrate_deploy() {
local output
info "Kör Prisma-migrationer (deploy)..."
info " ▶ Kör: npx prisma migrate deploy"
if ! output=$(docker exec recipe-api sh -lc "cd /app && npx prisma migrate deploy --schema prisma/schema.prisma" 2>&1); then
echo "$output"
fatal "Prisma migration misslyckades."
fi
echo "$output"
if echo "$output" | grep -qi "No pending migrations"; then
info "Migration-status: inga väntande migrationer."
elif echo "$output" | grep -qi "Applying migration"; then
info "Migration-status: minst en migration applicerades."
else
warn "Migration-status: kunde inte avgöra om nya migrationer applicerades."
fi
info "Migrationer slutförda utan fel."
}
for arg in "$@"; do
case "$arg" in
--backend) BUILD_BACKEND=true; BUILD_ALL=false ;;
--flutter) BUILD_FLUTTER=true; BUILD_ALL=false ;;
--importer) BUILD_IMPORTER=true; BUILD_ALL=false ;;
--seed) RUN_SEED=true ;;
--migrate) RUN_MIGRATE=true; BUILD_BACKEND=true; BUILD_ALL=false ;;
--skip-migration) SKIP_MIGRATION=true ;;
--clean-database) RUN_CLEAN_DATABASE=true; BUILD_BACKEND=true; BUILD_ALL=false ;;
--pull-always) PULL_IMAGES=true ;;
--help|-h)
sed -n '/^# Användning:/,/^[^#]/p' "$0" | grep '^#' | sed 's/^# \?//'
exit 0
;;
*) fatal "Okänd flagga: $arg (--help för hjälp)" ;;
esac
done
if [ "$BUILD_ALL" = true ]; then
BUILD_BACKEND=true
BUILD_FLUTTER=true
BUILD_IMPORTER=true
fi
# Om explicit migration begärs, stäng av automigrering i containern för att undvika dubbelkörning.
if [ "$RUN_MIGRATE" = true ]; then
SKIP_MIGRATION=true
fi
# ── Validering ────────────────────────────────────────────────────────────────
[ -f ".env" ] || fatal ".env saknas. Kör: cp .env.example .env && nano .env"
require_cmd git
require_cmd docker
if [ "$BUILD_BACKEND" = true ] || [ "$RUN_SEED" = true ] || [ "$RUN_CLEAN_DATABASE" = true ] || [ "$RUN_MIGRATE" = true ]; then
require_cmd grep
fi
export SKIP_MIGRATION
COMPOSE_CMD=(docker compose -f compose.yml -f compose.flutter.yml)
# ── Git pull ──────────────────────────────────────────────────────────────────
info "Hämtar senaste kod (recipe-app)..."
git pull origin main
if [ -d "$SCRIPT_DIR/../microservice-importer/.git" ]; then
info "Hämtar senaste kod (microservice-importer)..."
(cd "$SCRIPT_DIR/../microservice-importer" && git pull origin main)
else
warn "microservice-importer repo hittades inte på förväntad path, hoppar över git pull där."
fi
# ── Bygger valda tjänster ─────────────────────────────────────────────────────
SERVICES=()
[ "$BUILD_BACKEND" = true ] && SERVICES+=(recipe-api)
[ "$BUILD_FLUTTER" = true ] && SERVICES+=(recipe-flutter)
[ "$BUILD_IMPORTER" = true ] && SERVICES+=(importer-api)
if [ "${#SERVICES[@]}" -eq 0 ]; then
info "Bygger: alla tjänster..."
else
info "Bygger: ${SERVICES[*]}"
fi
if [ "$PULL_IMAGES" = true ]; then
info "(kontrollerar uppdateringar för basimages...)"
"${COMPOSE_CMD[@]}" build "${SERVICES[@]}"
else
"${COMPOSE_CMD[@]}" build --pull=false "${SERVICES[@]}"
fi
info "Startar tjänster..."
"${COMPOSE_CMD[@]}" up -d
# ── Prisma migreringar och databasrensning (opt-in) ─────────────────────────
if [ "$RUN_MIGRATE" = true ] || [ "$RUN_CLEAN_DATABASE" = true ]; then
CLEAN_SQL_FILE="backend/prisma/maintenance/clean-database.sql"
wait_for_backend_prisma || fatal "Backend blev inte redo för Prisma-kommandon i tid."
if [ "$RUN_MIGRATE" = true ]; then
run_prisma_migrate_deploy
fi
if [ "$RUN_CLEAN_DATABASE" = true ]; then
[ -f "$CLEAN_SQL_FILE" ] || fatal "Saknar $CLEAN_SQL_FILE"
MARIADB_ROOT_PASSWORD="$(read_env_value MARIADB_ROOT_PASSWORD)"
MARIADB_DATABASE="$(read_env_value MARIADB_DATABASE)"
[ -n "$MARIADB_ROOT_PASSWORD" ] || fatal "MARIADB_ROOT_PASSWORD saknas i .env"
[ -n "$MARIADB_DATABASE" ] || fatal "MARIADB_DATABASE saknas i .env"
info "Kör databasrensning från $CLEAN_SQL_FILE ..."
docker exec -i recipe-db mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" "$MARIADB_DATABASE" < "$CLEAN_SQL_FILE"
info "Databasrensning klar (kategorier bevarade enligt SQL-filen)."
fi
info "Uppdaterar Prisma Client..."
docker exec recipe-api sh -lc "cd /app && npx prisma generate --schema prisma/schema.prisma"
fi
# ── Seed (opt-in) ─────────────────────────────────────────────────────────────
if [ "$RUN_SEED" = true ]; then
MARIADB_ROOT_PASSWORD="$(read_env_value MARIADB_ROOT_PASSWORD)"
MARIADB_DATABASE="$(read_env_value MARIADB_DATABASE)"
[ -n "$MARIADB_ROOT_PASSWORD" ] || fatal "MARIADB_ROOT_PASSWORD saknas i .env"
[ -n "$MARIADB_DATABASE" ] || fatal "MARIADB_DATABASE saknas i .env"
wait_for_db "$MARIADB_ROOT_PASSWORD" || fatal "Databasen blev inte redo i tid."
if [ -f "db/seeds/seed_all.sql" ]; then
docker exec -i recipe-db mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" "$MARIADB_DATABASE" < db/seeds/seed_all.sql
info "Full seed klar."
else
warn "Ingen db/seeds/seed_all.sql hittades — hoppar över seed."
fi
fi
info "Status:"
"${COMPOSE_CMD[@]}" ps
END_TS="$(date +%s)"
DURATION="$((END_TS - START_TS))"
info "Deploy klart på ${DURATION}s."