feat: add order lifecycle integration tests (29 tests) and staging K8s deployment manifests

Testing (P0-7):
- 29 functional tests for order-service API (create/pay/complete/cancel lifecycle)
- CustomWebApplicationFactory with InMemory DB, mocked wallet/SignalR/tenant
- TestAuthHandler for JWT auth in tests
- Full lifecycle tests: cash flow and online payment flow end-to-end

Staging Deployment (P0-8):
- K8s manifests for 8 MVP services + Redis + POS web (namespace, configmap, secrets)
- Traefik Ingress with path-based routing and TLS via cert-manager
- HPA auto-scaling (2-4 replicas, CPU/memory thresholds)
- deploy-staging.sh script with --dry-run and --service flags
- CI/CD: deploy-staging.yml and docker-build.yml with matrix strategy
- Consistent patterns: port 8080, 3 health probes, RollingUpdate

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Ho Ngoc Hai
2026-03-06 13:56:03 +07:00
parent 914dda3fe9
commit 1d12a7980b
24 changed files with 3448 additions and 164 deletions

View File

@@ -1,21 +1,155 @@
#!/bin/bash
# EN: Deploy GoodGo Platform MVP services to Kubernetes staging environment
# VI: Trien khai cac service MVP cua GoodGo Platform len moi truong staging Kubernetes
#
# Prerequisites:
# - kubectl configured with staging cluster access (KUBECONFIG env var)
# - Docker images pushed to Docker Hub (goodgo/*:staging)
# - Secrets created via kubectl (see secrets.yaml for template)
#
# Usage:
# export KUBECONFIG=/path/to/kubeconfig
# ./scripts/deploy/deploy-staging.sh
# ./scripts/deploy/deploy-staging.sh --service iam-service # Deploy single service
# ./scripts/deploy/deploy-staging.sh --dry-run # Dry run mode
set -e
set -euo pipefail
echo "🚀 Deploying to staging..."
# EN: Color output helpers
# VI: Ham ho tro mau output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# EN: Verify KUBECONFIG environment variable is set
# VI: Xác minh biến môi trường KUBECONFIG đã được thiết lập
if [ -z "$KUBECONFIG" ]; then
echo "❌ KUBECONFIG environment variable not set"
DEPLOY_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/deployments/staging/kubernetes"
NAMESPACE="staging"
DRY_RUN=""
SINGLE_SERVICE=""
# EN: Parse arguments
# VI: Phan tich tham so
while [[ $# -gt 0 ]]; do
case $1 in
--dry-run)
DRY_RUN="--dry-run=client"
echo -e "${YELLOW}[DRY RUN] No changes will be applied${NC}"
shift
;;
--service)
SINGLE_SERVICE="$2"
shift 2
;;
*)
echo -e "${RED}Unknown option: $1${NC}"
exit 1
;;
esac
done
# EN: Verify KUBECONFIG
# VI: Xac minh KUBECONFIG
if [ -z "${KUBECONFIG:-}" ]; then
echo -e "${RED}KUBECONFIG environment variable not set${NC}"
echo "Usage: export KUBECONFIG=/path/to/kubeconfig && $0"
exit 1
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/
# EN: Verify kubectl connectivity
# VI: Xac minh ket noi kubectl
echo -e "${BLUE}Verifying kubectl connectivity...${NC}"
if ! kubectl cluster-info &>/dev/null; then
echo -e "${RED}Cannot connect to Kubernetes cluster. Check KUBECONFIG.${NC}"
exit 1
fi
echo "⏳ Waiting for rollout..."
kubectl rollout status deployment -n staging --timeout=90s || echo "⚠️ Some deployments might still be updating"
echo -e "${GREEN}=== GoodGo Platform - Staging Deployment ===${NC}"
echo -e "${BLUE}Namespace: ${NAMESPACE}${NC}"
echo -e "${BLUE}Manifests: ${DEPLOY_DIR}${NC}"
echo ""
echo "✅ Deployment completed!"
# EN: Step 1 - Apply namespace
# VI: Buoc 1 - Tao namespace
echo -e "${BLUE}[1/5] Applying namespace...${NC}"
kubectl apply -f "${DEPLOY_DIR}/namespace.yaml" ${DRY_RUN}
# EN: Step 2 - Apply shared configuration and secrets
# VI: Buoc 2 - Ap dung cau hinh chung va secrets
echo -e "${BLUE}[2/5] Applying configuration and secrets...${NC}"
kubectl apply -f "${DEPLOY_DIR}/configmap.yaml" ${DRY_RUN}
# EN: Only apply secrets.yaml if it doesn't contain PLACEHOLDER values
# VI: Chi ap dung secrets.yaml neu khong chua gia tri PLACEHOLDER
if grep -q "PLACEHOLDER" "${DEPLOY_DIR}/secrets.yaml"; then
echo -e "${YELLOW} WARNING: secrets.yaml contains PLACEHOLDER values.${NC}"
echo -e "${YELLOW} Skipping secrets apply. Use kubectl create secret or sealed-secrets.${NC}"
echo -e "${YELLOW} See secrets.yaml.example for reference.${NC}"
else
kubectl apply -f "${DEPLOY_DIR}/secrets.yaml" ${DRY_RUN}
fi
# EN: Step 3 - Deploy infrastructure (Redis)
# VI: Buoc 3 - Trien khai ha tang (Redis)
echo -e "${BLUE}[3/5] Deploying infrastructure...${NC}"
if [ -z "$SINGLE_SERVICE" ] || [ "$SINGLE_SERVICE" = "redis" ]; then
kubectl apply -f "${DEPLOY_DIR}/redis.yaml" ${DRY_RUN}
echo -e "${GREEN} redis deployed${NC}"
fi
# EN: Step 4 - Deploy backend services
# VI: Buoc 4 - Trien khai cac service backend
echo -e "${BLUE}[4/5] Deploying services...${NC}"
MVP_SERVICES=(
"iam-service"
"merchant-service"
"catalog-service"
"order-service"
"fnb-engine"
"inventory-service"
"wallet-service"
"storage-service"
"pos-web"
)
for svc in "${MVP_SERVICES[@]}"; do
if [ -z "$SINGLE_SERVICE" ] || [ "$SINGLE_SERVICE" = "$svc" ]; then
if [ -f "${DEPLOY_DIR}/${svc}.yaml" ]; then
kubectl apply -f "${DEPLOY_DIR}/${svc}.yaml" ${DRY_RUN}
echo -e "${GREEN} ${svc} deployed${NC}"
else
echo -e "${YELLOW} ${svc}.yaml not found, skipping${NC}"
fi
fi
done
# EN: Step 5 - Apply ingress routing
# VI: Buoc 5 - Ap dung dinh tuyen ingress
echo -e "${BLUE}[5/5] Applying ingress routing...${NC}"
if [ -z "$SINGLE_SERVICE" ]; then
kubectl apply -f "${DEPLOY_DIR}/ingress.yaml" ${DRY_RUN}
fi
echo ""
echo -e "${BLUE}Waiting for rollouts to complete...${NC}"
if [ -z "$DRY_RUN" ]; then
for svc in "${MVP_SERVICES[@]}"; do
if [ -z "$SINGLE_SERVICE" ] || [ "$SINGLE_SERVICE" = "$svc" ]; then
echo -n " ${svc}: "
if kubectl rollout status "deployment/${svc}" -n "${NAMESPACE}" --timeout=120s 2>/dev/null; then
echo -e "${GREEN}ready${NC}"
else
echo -e "${YELLOW}still updating (check: kubectl get pods -n ${NAMESPACE} -l app=${svc})${NC}"
fi
fi
done
fi
echo ""
echo -e "${GREEN}=== Staging deployment completed ===${NC}"
echo -e "${BLUE}API: https://api.staging.goodgo.vn${NC}"
echo -e "${BLUE}POS: https://pos.staging.goodgo.vn${NC}"
echo ""
echo -e "Verify: kubectl get pods -n ${NAMESPACE}"
echo -e "Logs: kubectl logs -n ${NAMESPACE} -l app=<service-name> -f"