Implement code changes to enhance functionality and improve performance #217
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | |
| 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: Copy user-service files for context | |
| run: | | |
| mkdir -p /tmp/build-context | |
| cp -r ../redis-client-lib /tmp/build-context/ | |
| cp -r . /tmp/build-context/user-service | |
| working-directory: ./user-service | |
| - 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 | |
| - id: "auth" | |
| name: "Authenticate to Google Cloud" | |
| uses: "google-github-actions/auth@v1" | |
| with: | |
| credentials_json: "${{ secrets.GCP_SA_KEY }}" | |
| - name: "Set up Cloud SDK" | |
| uses: "google-github-actions/setup-gcloud@v1" | |
| - 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 "=== Testing Directory Access ===" | |
| mkdir -p /opt/craftpilot | |
| echo "=== Continuing with Deployment ===" | |
| echo '${{ secrets.GCP_SA_KEY }}' > /opt/craftpilot/gcp-credentials.json | |
| chmod 600 /opt/craftpilot/gcp-credentials.json | |
| echo "=== Verifying Docker Status ===" | |
| if ! systemctl is-active --quiet docker; then | |
| echo "Docker is not running. Starting Docker..." | |
| sudo systemctl start docker | |
| fi | |
| echo "=== Deploying User Service ===" | |
| # Force pull latest image | |
| docker pull ${{ secrets.DOCKERHUB_USERNAME }}/user-service:latest-arm64 | |
| echo "=== Stopping Old Container ===" | |
| docker rm -f user-service || true | |
| echo "=== Starting 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 \ | |
| -v /opt/craftpilot/gcp/credentials.json:/etc/gcp/credentials/gcp-credentials.json:ro \ | |
| -e GOOGLE_APPLICATION_CREDENTIALS=/etc/gcp/credentials/gcp-credentials.json \ | |
| -e FIREBASE_CONFIG_PATH=/etc/gcp/credentials/gcp-credentials.json \ | |
| -e SPRING_PROFILES_ACTIVE=prod \ | |
| -e SERVER_PORT=8060 \ | |
| -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 REDIS_HOST=redis \ | |
| -e REDIS_PORT=6379 \ | |
| -e REDIS_PASSWORD=13579ada \ | |
| -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 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 "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 \ | |
| -v /opt/craftpilot/gcp/credentials.json:/etc/gcp/credentials/gcp-credentials.json:ro \ | |
| -e GOOGLE_APPLICATION_CREDENTIALS=/etc/gcp/credentials/gcp-credentials.json \ | |
| -e FIREBASE_CONFIG_PATH=/etc/gcp/credentials/gcp-credentials.json \ | |
| -e SPRING_PROFILES_ACTIVE=prod \ | |
| -e SERVER_PORT=8060 \ | |
| -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 REDIS_HOST=redis \ | |
| -e REDIS_PORT=6379 \ | |
| -e REDIS_PASSWORD=13579ada \ | |
| -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 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 | |
| echo "✓ Service is healthy: $HEALTH_CHECK" | |
| echo "=== Deployment completed successfully ===" | |
| exit 0 | |
| 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 "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 |