Skip to content

feat(model): modelId alanı için güncellemeler yapıldı; AIModelService… #348

feat(model): modelId alanı için güncellemeler yapıldı; AIModelService…

feat(model): modelId alanı için güncellemeler yapıldı; AIModelService… #348

name: User Service CI/CD
on:
push:
branches: [master]
paths:
- "user-service/**"
- "redis-client-lib/**"
- ".github/workflows/user-service-ci-cd.yml"
pull_request:
branches: [master]
paths:
- "user-service/**"
- "redis-client-lib/**"
workflow_dispatch:
inputs:
environment:
description: "Environment to deploy to"
required: true
default: "prod"
type: choice
options:
- prod
- debug
clean_cache:
description: "Clean all caches before deployment"
required: false
default: true
type: boolean
jobs:
build-and-deploy:
runs-on: self-hosted
defaults:
run:
working-directory: ./user-service
steps:
- uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
with:
platforms: arm64
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
platforms: linux/arm64
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
logout: true
- name: Clean local Docker cache
run: |
echo "Cleaning local Docker cache for user-service and redis-client-lib"
docker system prune -af --filter "label=com.docker.compose.project=user-service" || true
docker images "${{ secrets.DOCKERHUB_USERNAME }}/user-service" --format "{{.ID}}" | xargs -r docker rmi -f || true
docker builder prune -af || true
- name: Clean local Maven cache
run: |
echo "Cleaning local Maven cache for user-service and redis-client-lib"
rm -rf ~/.m2/repository/com/craftpilot/user-service || true
rm -rf ~/.m2/repository/com/craftpilot/redis-client-lib || true
rm -rf ~/.m2/repository/org/mapstruct || true
find . -name "*MapperImpl*.java" -delete || true
- name: Prepare clean build context
run: |
mkdir -p /tmp/build-context
cp -r ../redis-client-lib /tmp/build-context/
cp -r . /tmp/build-context/user-service
# Clean any generated files to prevent MapStruct issues
find /tmp/build-context -name "target" -type d -exec rm -rf {} + 2>/dev/null || true
find /tmp/build-context -name "*MapperImpl*.java" -delete || true
find /tmp/build-context -name "*.class" -delete || true
- name: Build and Push Docker image
uses: docker/build-push-action@v4
with:
context: /tmp/build-context
file: /tmp/build-context/user-service/Dockerfile
platforms: linux/arm64
push: true
tags: |
${{ secrets.DOCKERHUB_USERNAME }}/user-service:latest-arm64
${{ secrets.DOCKERHUB_USERNAME }}/user-service:${{ github.sha }}-arm64
cache-from: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/user-service:buildcache-arm64
cache-to: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/user-service:buildcache-arm64,mode=max
no-cache: true
pull: true
- name: Deploy to VPS
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
command_timeout: "20m"
debug: true
script: |
set -e # Exit on any error
echo "=== Testing SSH Connection ==="
whoami
pwd
echo "=== System Architecture ==="
uname -m
echo "=== Cleaning Remote Caches ==="
echo "Cleaning Docker cache..."
docker system prune -af --filter "until=24h" --filter "label!=persistence=keep" || true
docker images "${{ secrets.DOCKERHUB_USERNAME }}/user-service" --format "{{.ID}}" | xargs -r docker rmi -f || true
echo "Cleaning Maven cache..."
rm -rf ~/.m2/repository/com/craftpilot/user-service || true
rm -rf ~/.m2/repository/com/craftpilot/redis-client-lib || true
echo "Cleaning Redis cache related to user-service..."
docker exec -i redis redis-cli -a 13579ada KEYS "user:preferences:*" | xargs -r docker exec -i redis redis-cli -a 13579ada DEL || true
echo "=== Testing Directory Access ==="
mkdir -p /opt/craftpilot
echo "=== Docker Network Availability ==="
docker network create craftpilot-network || true
echo "=== MongoDB Container Check ==="
MONGODB_CONTAINER="craftpilot-mongodb"
if ! docker ps | grep -q "$MONGODB_CONTAINER"; then
echo "WARNING: Default MongoDB container not found ($MONGODB_CONTAINER)"
# Fallback to detect any MongoDB container
MONGODB_CONTAINER=$(docker ps --format '{{.Names}}' | grep -E 'mongo|mongodb' | head -n 1)
if [ -z "$MONGODB_CONTAINER" ]; then
echo "ERROR: No MongoDB container found! Using default name, but connection may fail."
MONGODB_CONTAINER="craftpilot-mongodb" # Fallback to default
else
echo "Found alternative MongoDB container: $MONGODB_CONTAINER"
fi
fi
echo "Using MongoDB container: $MONGODB_CONTAINER"
echo "=== MongoDB Connection Test ==="
if docker run --rm --network craftpilot-network mongo:6.0 mongosh --quiet --eval "db.runCommand({ping:1}).ok" admin --host $MONGODB_CONTAINER --port 27017 -u ${{ secrets.MONGO_ROOT_USERNAME }} -p ${{ secrets.MONGO_ROOT_PASSWORD }} --authenticationDatabase admin | grep -q "1"; then
echo "✅ MongoDB connection test successful!"
else
echo "⚠️ MongoDB connection test failed! Deployment will continue but may have issues."
fi
echo "=== MongoDB URI Construction ==="
# Parse the URI if provided, otherwise construct from components
if [ -n "${{ secrets.MONGODB_URI }}" ]; then
# Parse the URI and replace the hostname with our container name
URI_PREFIX=$(echo "${{ secrets.MONGODB_URI }}" | grep -oP 'mongodb://[^@]+@')
URI_SUFFIX=$(echo "${{ secrets.MONGODB_URI }}" | grep -oP '(?<=@)[^/]+/.*')
URI_HOST=$(echo "$URI_SUFFIX" | grep -oP '^[^:/]+')
URI_REMAINDER=$(echo "$URI_SUFFIX" | grep -oP '(?<='"$URI_HOST"')[:/].*')
MONGODB_URI="${URI_PREFIX}${MONGODB_CONTAINER}${URI_REMAINDER}"
echo "Modified MongoDB URI with correct container name: $(echo $MONGODB_URI | sed 's/:[^:]*@/:*****@/g')"
else
# Build URI from components
MONGODB_URI="mongodb://${{ secrets.MONGO_ROOT_USERNAME }}:${{ secrets.MONGO_ROOT_PASSWORD }}@${MONGODB_CONTAINER}:27017/craftpilot_user_db?authSource=admin&retryWrites=true&w=majority&serverSelectionTimeoutMS=60000"
echo "Built MongoDB URI from credential components: $(echo $MONGODB_URI | sed 's/:[^:]*@/:*****@/g')"
fi
echo "=== Stopping Old Container ==="
docker rm -f user-service || true
echo "=== Pulling Latest Image ==="
docker pull ${{ secrets.DOCKERHUB_USERNAME }}/user-service:latest-arm64
echo "=== Deploying User Service ==="
if [[ "${{ github.event.inputs.environment }}" == "debug" ]]; then
docker run -d \
--name user-service \
--network craftpilot-network \
--restart unless-stopped \
-p 8060:8060 \
-p 5007:5007 \
-e SPRING_PROFILES_ACTIVE=prod \
-e SERVER_PORT=8060 \
-e SPRING_DATA_MONGODB_URI="$MONGODB_URI" \
-e SPRING_DATA_MONGODB_DATABASE="craftpilot_user_db" \
-e SPRING_DATA_MONGODB_CONNECTION_TIMEOUT=30000 \
-e SPRING_DATA_MONGODB_SOCKET_TIMEOUT=60000 \
-e SPRING_DATA_MONGODB_MAX_CONNECTION_IDLE_TIME=300000 \
-e SPRING_DATA_MONGODB_CONNECTION_POOL_MAX_SIZE=20 \
-e EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=http://craftpilot:13579ada@eureka-server:8761/eureka/ \
-e EUREKA_INSTANCE_HOSTNAME=user-service \
-e EUREKA_INSTANCE_PREFER_IP_ADDRESS=false \
-e KAFKA_BOOTSTRAP_SERVERS=kafka:9092 \
-e KAFKA_ENABLED=true \
-e REDIS_HOST=redis \
-e REDIS_PORT=6379 \
-e REDIS_PASSWORD=13579ada \
-e REDIS_TIMEOUT=2000 \
-e REDIS_DATABASE=0 \
-e MANAGEMENT_HEALTH_VALIDATE_GROUP_MEMBERSHIP=false \
-e MANAGEMENT_ENDPOINT_HEALTH_PROBES_ENABLED=true \
-e MANAGEMENT_HEALTH_LIVENESSSTATE_ENABLED=true \
-e MANAGEMENT_HEALTH_READINESSSTATE_ENABLED=true \
-e MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE="health,info,metrics,loggers,env" \
-e MANAGEMENT_ENDPOINT_HEALTH_SHOW_DETAILS=always \
-e MANAGEMENT_HEALTH_MONGODB_ENABLED=true \
-e SPRING_APPLICATION_NAME=user-service \
-e LOGGING_LEVEL_COM_CRAFTPILOT=DEBUG \
-e LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_CLOUD_NETFLIX_EUREKA=DEBUG \
-e LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_DATA_REDIS=DEBUG \
-e LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_DATA_MONGODB=DEBUG \
-e LOGGING_LEVEL_COM_CRAFTPILOT_USERSERVICE_CONFIG=TRACE \
-e "JAVA_TOOL_OPTIONS=-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5007" \
--health-cmd="curl -f http://localhost:8060/actuator/health || exit 1" \
--health-interval=10s \
--health-retries=10 \
--health-timeout=5s \
--health-start-period=60s \
${{ secrets.DOCKERHUB_USERNAME }}/user-service:latest-arm64
else
docker run -d \
--name user-service \
--network craftpilot-network \
--restart unless-stopped \
-p 8060:8060 \
-e SPRING_PROFILES_ACTIVE=prod \
-e SERVER_PORT=8060 \
-e SPRING_DATA_MONGODB_URI="$MONGODB_URI" \
-e SPRING_DATA_MONGODB_DATABASE="craftpilot_user_db" \
-e SPRING_DATA_MONGODB_CONNECTION_TIMEOUT=30000 \
-e SPRING_DATA_MONGODB_SOCKET_TIMEOUT=60000 \
-e SPRING_DATA_MONGODB_MAX_CONNECTION_IDLE_TIME=300000 \
-e SPRING_DATA_MONGODB_CONNECTION_POOL_MAX_SIZE=20 \
-e EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=http://craftpilot:13579ada@eureka-server:8761/eureka/ \
-e EUREKA_INSTANCE_HOSTNAME=user-service \
-e EUREKA_INSTANCE_PREFER_IP_ADDRESS=false \
-e KAFKA_BOOTSTRAP_SERVERS=kafka:9092 \
-e KAFKA_ENABLED=true \
-e REDIS_HOST=redis \
-e REDIS_PORT=6379 \
-e REDIS_PASSWORD=13579ada \
-e REDIS_TIMEOUT=2000 \
-e REDIS_DATABASE=0 \
-e MANAGEMENT_HEALTH_VALIDATE_GROUP_MEMBERSHIP=false \
-e MANAGEMENT_ENDPOINT_HEALTH_PROBES_ENABLED=true \
-e MANAGEMENT_HEALTH_LIVENESSSTATE_ENABLED=true \
-e MANAGEMENT_HEALTH_READINESSSTATE_ENABLED=true \
-e MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE="health,info,metrics" \
-e MANAGEMENT_ENDPOINT_HEALTH_SHOW_DETAILS=always \
-e MANAGEMENT_HEALTH_MONGODB_ENABLED=true \
-e SPRING_APPLICATION_NAME=user-service \
--health-cmd="curl -f http://localhost:8060/actuator/health || exit 1" \
--health-interval=10s \
--health-retries=10 \
--health-timeout=5s \
--health-start-period=40s \
${{ secrets.DOCKERHUB_USERNAME }}/user-service:latest-arm64
fi
echo "=== Waiting for Service to Start ==="
max_attempts=20
counter=0
while [ $counter -lt $max_attempts ]; do
echo "Health check attempt $((counter + 1))/$max_attempts"
# Container status check
if ! docker ps --filter "name=user-service" --format '{{.Status}}' | grep -q "Up"; then
echo "Container is not running anymore. Checking logs..."
docker logs user-service --tail 100
exit 1
fi
# Health check
HEALTH_CHECK=$(curl -s http://localhost:8060/actuator/health || echo "Failed to connect")
if echo "$HEALTH_CHECK" | grep -q '"status":"UP"'; then
if echo "$HEALTH_CHECK" | grep -q '"mongo":{.*"status":"UP"'; then
echo "✅ Service is healthy with MongoDB connection: $HEALTH_CHECK"
echo "=== Deployment completed successfully ==="
exit 0
else
echo "Service is UP but MongoDB component status needs verification."
fi
else
echo "Health check response: $HEALTH_CHECK"
fi
echo "Waiting for service to start... ($((counter + 1))/$max_attempts)"
sleep 15
counter=$((counter + 1))
done
echo "=== Service Failed to Start - Debug Information ==="
echo "Docker Container Status:"
docker ps -a | grep user-service
echo "Container Logs (last 100 lines):"
docker logs user-service --tail 100
echo "MongoDB Connection Test:"
docker exec user-service nc -zv $MONGODB_CONTAINER 27017 || echo "Cannot connect to MongoDB"
echo "Error Messages and Exceptions:"
docker logs user-service 2>&1 | grep -i "error\|exception\|failed" | tail -20
echo "Health Check Response:"
curl -v http://localhost:8060/actuator/health || true
exit 1