From c9ec3194bac2b06780a44a2afc3a599f4b90d221 Mon Sep 17 00:00:00 2001 From: Ho Ngoc Hai Date: Sat, 17 Jan 2026 21:50:14 +0700 Subject: [PATCH] Update Scripts --- scripts/db/migrate.sh | 128 +++++++++++++++++++++++-------- scripts/deploy/deploy-prod.sh | 6 +- scripts/deploy/deploy-staging.sh | 4 +- scripts/dev/logs.sh | 50 ++++++++---- 4 files changed, 140 insertions(+), 48 deletions(-) diff --git a/scripts/db/migrate.sh b/scripts/db/migrate.sh index ed31aaf0..bf4855af 100755 --- a/scripts/db/migrate.sh +++ b/scripts/db/migrate.sh @@ -1,5 +1,5 @@ #!/bin/bash -# VI: Script migration database cho từng service riêng lẻ +# VI: Script migration database cho từng service riêng lẻ (Polyglot: Node/Prisma & .NET/EF Core) set -e @@ -10,65 +10,127 @@ MODE=$2 if [ -z "$SERVICE" ]; then echo "Cách dùng: $0 [dev|deploy|reset]" echo "Ví dụ: $0 iam-service dev" - echo "Ví dụ: $0 iam-service deploy" - echo "Ví dụ: $0 iam-service reset" + echo "Ví dụ: $0 mission-service-net dev" exit 1 fi # VI: Kiểm tra thư mục service có tồn tại không -if [ ! -d "services/$SERVICE" ]; then +SERVICE_PATH="services/$SERVICE" +if [ ! -d "$SERVICE_PATH" ]; then echo "❌ Không tìm thấy service $SERVICE" exit 1 fi echo "🔄 Chạy migrations cho $SERVICE..." -cd "services/$SERVICE" +cd "$SERVICE_PATH" + +# ----------------------------------------------------------------------------- +# 1. Environment Setup (Common) +# ----------------------------------------------------------------------------- # VI: Load biến môi trường (hybrid pattern) -# VI: 1. Load shared env (JWT secrets, Redis config) if [ -f "../../deployments/local/.env.local" ]; then set -a source ../../deployments/local/.env.local set +a fi -# VI: 2. Load service-specific env (DATABASE_URL, PORT, etc.) if [ -f ".env.local" ]; then set -a source .env.local set +a fi -# VI: Kiểm tra DATABASE_URL có được thiết lập không -if [ -z "$DATABASE_URL" ]; then - echo "⚠️ DATABASE_URL chưa được thiết lập. Vui lòng kiểm tra file .env.local:" - echo " - Shared config: ../../deployments/local/.env.local" - echo " - Service config: .env.local" - echo " Ví dụ Neon: postgresql://user:pass@ep-xxx.region.neon.tech/dbname?sslmode=require" - exit 1 -fi +# ----------------------------------------------------------------------------- +# 2. Logic Selection (Node vs .NET) +# ----------------------------------------------------------------------------- -# VI: Thực hiện migration dựa trên mode -if [ "$MODE" = "dev" ]; then - echo "📝 Chạy development migration (tạo migration mới)..." - pnpm prisma migrate dev -elif [ "$MODE" = "deploy" ]; then - echo "🚀 Chạy production migration (áp dụng migrations có sẵn)..." - pnpm prisma migrate deploy - pnpm prisma generate -elif [ "$MODE" = "reset" ]; then - echo "⚠️ CẢNH BÁO: Sẽ xóa toàn bộ database và chạy lại migrations!" - read -p "Bạn có chắc chắn? (yes/no): " confirm - if [ "$confirm" = "yes" ]; then - echo "🔄 Reset database..." - pnpm prisma migrate reset --force - else - echo "❌ Hủy reset database" - exit 0 +# A. Node.js with Prisma +if [ -f "prisma/schema.prisma" ] || [ -f "package.json" ]; then + echo " 📦 Detected Node.js/Prisma project" + + # VI: Kiểm tra DATABASE_URL (Prisma cần cái này) + if [ -z "$DATABASE_URL" ]; then + echo "⚠️ DATABASE_URL chưa được thiết lập." + exit 1 fi + + if [ "$MODE" = "dev" ]; then + echo "📝 Chạy Prisma migrate dev..." + pnpm prisma migrate dev + elif [ "$MODE" = "deploy" ]; then + echo "🚀 Chạy Prisma migrate deploy..." + pnpm prisma migrate deploy + pnpm prisma generate + elif [ "$MODE" = "reset" ]; then + echo "⚠️ CẢNH BÁO: Reset database!" + read -p "Bạn có chắc chắn? (yes/no): " confirm + if [ "$confirm" = "yes" ]; then + pnpm prisma migrate reset --force + fi + else + echo "❌ Mode không hợp lệ cho Node.js: dev, deploy, reset" + exit 1 + fi + +# B. .NET with Entity Framework Core +elif compgen -G "*.sln" > /dev/null || compgen -G "src/*.sln" > /dev/null || compgen -G "*.csproj" > /dev/null; then + echo " 📦 Detected .NET/EF Core project" + + # Locate the Project (API or Infrastructure usually holds the DbContext, but we run commands against the executable or startup project) + # Usually we run `dotnet ef` against the API project (startup) or Infrastructure (where DbContext is). + # Best practice: Run against startup project (API) which has connection strings. + + STARTUP_PROJECT="." + if [ -d "src" ]; then + # Try to find API project + API_PROJ=$(find src -name "*.API.csproj" | head -n 1) + if [ -n "$API_PROJ" ]; then + STARTUP_PROJECT="$API_PROJ" + fi + fi + + echo " 👉 Using startup project: $STARTUP_PROJECT" + + # Check for dotnet-ef tool + if ! dotnet tool list -g | grep -q "dotnet-ef"; then + echo "⚠️ dotnet-ef tool not found globally. Installing..." + dotnet tool install --global dotnet-ef || true + fi + + if [ "$MODE" = "dev" ]; then + echo "📝 Creating new migration (dotnet ef migrations add)..." + read -p "Enter migration name (e.g. AddUsersTable): " migr_name + if [ -z "$migr_name" ]; then + migr_name="Migration_$(date +%Y%m%d%H%M%S)" + fi + dotnet ef migrations add "$migr_name" --project "$STARTUP_PROJECT" + + echo "Do you want to apply it now? (y/n)" + read -p "> " apply_now + if [ "$apply_now" = "y" ]; then + dotnet ef database update --project "$STARTUP_PROJECT" + fi + + elif [ "$MODE" = "deploy" ]; then + echo "🚀 Applying migrations (dotnet ef database update)..." + dotnet ef database update --project "$STARTUP_PROJECT" + + elif [ "$MODE" = "reset" ]; then + echo "⚠️ CẢNH BÁO: Drop database & Update!" + read -p "Confirm? (yes/no): " confirm + if [ "$confirm" = "yes" ]; then + dotnet ef database drop --force --project "$STARTUP_PROJECT" + dotnet ef database update --project "$STARTUP_PROJECT" + fi + else + echo "❌ Mode invalid for .NET: dev, deploy, reset" + exit 1 + fi + else - echo "⚠️ Mode không hợp lệ. Sử dụng: dev, deploy, hoặc reset" + echo "❌ Unknown project type (Environment not supported)" exit 1 fi diff --git a/scripts/deploy/deploy-prod.sh b/scripts/deploy/deploy-prod.sh index 1fa067c7..a33c57ef 100755 --- a/scripts/deploy/deploy-prod.sh +++ b/scripts/deploy/deploy-prod.sh @@ -26,6 +26,10 @@ fi # EN: Apply Kubernetes configurations and wait for rollout # VI: Áp dụng cấu hình Kubernetes và đợi quá trình rollout hoàn tất kubectl apply -f deployments/production/kubernetes/ -kubectl rollout status deployment/iam-service -n production + +echo "⏳ Waiting for rollout..." +# EN: Wait for all deployments in the namespace +# VI: Đợi tất cả deployments trong namespace +kubectl rollout status deployment -n production --timeout=90s || echo "⚠️ Some deployments might still be updating" echo "✅ Deployment completed!" diff --git a/scripts/deploy/deploy-staging.sh b/scripts/deploy/deploy-staging.sh index 3e13848f..6186379a 100755 --- a/scripts/deploy/deploy-staging.sh +++ b/scripts/deploy/deploy-staging.sh @@ -14,6 +14,8 @@ fi # EN: Apply Kubernetes configurations and wait for rollout # VI: Áp dụng cấu hình Kubernetes và đợi quá trình rollout hoàn tất kubectl apply -f deployments/staging/kubernetes/ -kubectl rollout status deployment/iam-service -n staging + +echo "⏳ Waiting for rollout..." +kubectl rollout status deployment -n staging --timeout=90s || echo "⚠️ Some deployments might still be updating" echo "✅ Deployment completed!" diff --git a/scripts/dev/logs.sh b/scripts/dev/logs.sh index 03230e2e..3b45d262 100755 --- a/scripts/dev/logs.sh +++ b/scripts/dev/logs.sh @@ -1,32 +1,56 @@ #!/bin/bash SERVICE=$1 +MODE=$2 # EN: Check usage # VI: Kiểm tra cách sử dụng if [ -z "$SERVICE" ]; then - echo "Usage: $0 / Cách dùng: $0 " + echo "Usage: $0 " echo "Example: $0 iam-service" - echo "" - echo "Or use 'docker' to view Docker logs: / Hoặc dùng 'docker' để xem log Docker:" - echo " $0 docker " + echo "Example: $0 mission-service-net" exit 1 fi if [ "$SERVICE" = "docker" ]; then + # Legacy support: ./logs.sh docker CONTAINER=$2 if [ -z "$CONTAINER" ]; then - echo "Usage: $0 docker " - echo "Available containers: / Các container khả dụng:" docker ps --format "{{.Names}}" exit 1 fi - # EN: Follow docker logs - # VI: Theo dõi log docker docker logs -f "$CONTAINER" -else - # EN: Start development logs using pnpm - # VI: Bắt đầu log phát triển sử dụng pnpm - cd "services/$SERVICE" - pnpm dev + exit 0 fi + +# Smart Detection +# Try to find a docker container that Matches or Contains the service name +# Common prefixes/suffixes: -local, goodgo-, etc. + +# 1. Exact match +if docker ps --format "{{.Names}}" | grep -q "^${SERVICE}$"; then + echo "📦 Found exact container match. Tailing logs..." + docker logs -f "$SERVICE" + exit 0 +fi + +# 2. Local suffix match (e.g. service-name-local, -net-local) +SUFFIX_MATCH="${SERVICE}-local" +if docker ps --format "{{.Names}}" | grep -q "${SUFFIX_MATCH}"; then + echo "📦 Found container: $SUFFIX_MATCH" + docker logs -f "$SUFFIX_MATCH" + exit 0 +fi + +# 3. Fuzzy match (head -n 1) +FUZZY=$(docker ps --format "{{.Names}}" | grep "$SERVICE" | head -n 1) +if [ -n "$FUZZY" ]; then + echo "📦 Found fuzzy match: $FUZZY" + docker logs -f "$FUZZY" + exit 0 +fi + +# 4. If no docker container found, and it's a Node app, maybe user wants pnpm log? +# But typically we don't use this script for local pnpm unless wrapped. +echo "❌ No running container found for $SERVICE." +echo " If you are running it locally (non-Docker), check the terminal window where you started it."