@@ -99,85 +99,57 @@ jobs:
9999 script : |
100100 set -e
101101
102- echo "📚 Generating API documentation ..."
102+ echo "📚 Starting staging deployment build process ..."
103103
104104 # Navigate to application directory
105105 cd ${{ secrets.STAGING_APP_PATH || '/opt/trends-earth-api-staging' }}
106106
107- # Pull latest changes and checkout the correct branch
108- git fetch origin
107+ # Ensure deployment utilities are executable
108+ chmod +x scripts/deployment_utils.py
109109
110- # Determine which branch to deploy and checkout
111- if [ "${{ github.ref_name }}" = "staging" ]; then
112- echo "🔄 Checking out staging branch..."
113- git checkout staging
114- git reset --hard origin/staging
115- else
116- echo "🔄 Checking out develop branch..."
117- git checkout develop
118- git reset --hard origin/develop
119- fi
120-
121- echo "✅ Currently on branch: $(git branch --show-current)"
110+ # Determine which branch to deploy
111+ BRANCH="${{ github.ref_name == 'staging' && 'staging' || 'develop' }}"
112+ echo "� Deploying branch: $BRANCH"
122113
123- # Configure insecure registry on server if needed
124- echo "📋 Configuring insecure registry on server..."
125- sudo mkdir -p /etc/docker
126- if [ ! -f /etc/docker/daemon.json ] || ! grep -q "insecure-registries" /etc/docker/daemon.json; then
127- echo '{"insecure-registries":["${{ env.REGISTRY }}"]}' | sudo tee /etc/docker/daemon.json > /dev/null
128- sudo systemctl restart docker
129- sleep 10
114+ # Clean git workspace and checkout correct branch using deployment utilities
115+ if ! python3 scripts/deployment_utils.py \
116+ --registry "${{ env.REGISTRY }}" \
117+ --image-name "${{ env.IMAGE_NAME }}" \
118+ --app-path "${{ secrets.STAGING_APP_PATH || '/opt/trends-earth-api-staging' }}" \
119+ clean-git --branch "$BRANCH"; then
120+ echo "❌ Git workspace cleaning failed"
121+ exit 1
130122 fi
131123
132- # Configure Docker client authentication
133- mkdir -p $HOME/.docker
134-
135- # Create simplified Docker config without auth for staging
136- echo "🔐 Creating Docker config for staging..."
137- cat > $HOME/.docker/config.json <<-DOCKERCONFIG
138- {
139- "insecure-registries": ["${{ env.REGISTRY }}"]
140- }
141- DOCKERCONFIG
142- echo "✅ Docker config created successfully"
143-
144- # Build the image with the appropriate tags
145- echo "🔨 Building Docker image..."
124+ # Configure Docker registry using deployment utilities
125+ if ! python3 scripts/deployment_utils.py \
126+ --registry "${{ env.REGISTRY }}" \
127+ --image-name "${{ env.IMAGE_NAME }}" \
128+ --app-path "${{ secrets.STAGING_APP_PATH || '/opt/trends-earth-api-staging' }}" \
129+ configure-registry; then
130+ echo "❌ Docker registry configuration failed"
131+ exit 1
132+ fi
146133
147- # Create staging-specific tags
148- REGISTRY="${{ env.REGISTRY }}"
149- IMAGE_NAME="${{ env.IMAGE_NAME }}"
134+ # Create image tags for staging deployment
150135 BRANCH_NAME="${{ github.ref_name }}"
151136 SHORT_SHA="${{ github.sha }}"
152137 SHORT_SHA="${SHORT_SHA:0:7}"
153138
154- BUILT_TAGS="$REGISTRY/$IMAGE_NAME:$BRANCH_NAME
155- $REGISTRY/$IMAGE_NAME:$BRANCH_NAME-$SHORT_SHA
156- $REGISTRY/$IMAGE_NAME:staging"
157-
158- # Build with the first tag (primary tag)
159- PRIMARY_TAG="$REGISTRY/$IMAGE_NAME:$BRANCH_NAME"
160- echo "Building with primary tag: $PRIMARY_TAG"
161- docker build --no-cache -t "$PRIMARY_TAG" .
162-
163- # Tag with additional tags
164- echo "$BUILT_TAGS" | while IFS= read -r tag; do
165- if [ -n "$tag" ] && [ "$tag" != "$PRIMARY_TAG" ]; then
166- echo "Tagging with: $tag"
167- docker tag "$PRIMARY_TAG" "$tag"
168- fi
169- done
170-
171- # Push all tags to the local registry
172- echo "🚀 Pushing images to local registry..."
173- echo "$BUILT_TAGS" | while IFS= read -r tag; do
174- if [ -n "$tag" ]; then
175- echo "Pushing: $tag"
176- docker push "$tag"
177- fi
178- done
139+ # Build and push images using deployment utilities
140+ if ! python3 scripts/deployment_utils.py \
141+ --registry "${{ env.REGISTRY }}" \
142+ --image-name "${{ env.IMAGE_NAME }}" \
143+ --app-path "${{ secrets.STAGING_APP_PATH || '/opt/trends-earth-api-staging' }}" \
144+ build-image \
145+ --tags "$BRANCH_NAME" "$BRANCH_NAME-$SHORT_SHA" "staging" \
146+ --commit-sha "${{ github.sha }}" \
147+ --no-cache; then
148+ echo "❌ Docker image build and push failed"
149+ exit 1
150+ fi
179151
180- echo "✅ Image build and push completed!"
152+ echo "✅ Staging deployment build process completed!"
181153
182154 - name : Deploy to EC2 Staging
183155 uses : appleboy/ssh-action@v1.0.0
@@ -385,69 +357,28 @@ jobs:
385357 fi
386358 fi
387359
388- # Check that all services are running with desired replicas
360+ # Wait for all services to be ready using deployment utilities
389361 echo "📊 Waiting for all services to be running..."
390- max_wait=120
391- wait_time=0
392-
393- while [ $wait_time -lt $max_wait ]; do
394- # Check if all services have desired replicas running
395- pending_services=$(docker service ls --filter "name=trends-earth-staging" --format "table {{.Name}}\t{{.Replicas}}" | grep -v "1/1" | wc -l)
396-
397- # Migrate when running correctly will run once then exit, so we expect 1 service to not be replicated
398- if [ $pending_services -eq 2 ]; then # Only header line and migrate line should remain if all other services are 1/1
399- echo "✅ All services are running"
400- break
401- fi
402-
403- echo "⏳ Waiting for services to be ready... ($wait_time/$max_wait seconds)"
404- docker service ls --filter "name=trends-earth-staging"
405- sleep 10
406- wait_time=$((wait_time + 10))
407- done
408-
409- if [ $wait_time -ge $max_wait ]; then
410- echo "⚠️ Some services may not be fully ready after $max_wait seconds"
362+ if ! python3 scripts/deployment_utils.py \
363+ --registry "${{ secrets.DOCKER_REGISTRY }}" \
364+ --image-name "${{ env.IMAGE_NAME }}" \
365+ --app-path "${{ secrets.STAGING_APP_PATH || '/opt/trends-earth-api-staging' }}" \
366+ wait-services --stack-name "trends-earth-staging" --max-wait 120; then
367+ echo "⚠️ Some services may not be fully ready, but continuing..."
411368 fi
412369
413370 # Check service status
414371 echo "📊 Final service status:"
415372 docker service ls | grep trends-earth-staging
416373
417- # Health check
374+ # Health check using deployment utilities
418375 echo "🏥 Performing health check..."
419- max_attempts=30
420- attempt=1
421-
422- while [ $attempt -le $max_attempts ]; do
423- echo "⏳ Health check attempt $attempt/$max_attempts..."
424-
425- # First check if port is listening
426- if ! nc -z 127.0.0.1 3002 2>/dev/null; then
427- echo "⚠️ Port 3002 is not listening yet"
428- else
429- echo "✅ Port 3002 is listening"
430- fi
431-
432- # Perform health check request
433- health_response=$(curl -f -s -w "HTTP_CODE:%{http_code}" http://127.0.0.1:3002/api-health 2>&1)
434- curl_exit_code=$?
435-
436- if [ $curl_exit_code -eq 0 ]; then
437- echo "✅ Health check passed"
438- echo "Response: $health_response"
439- break
440- else
441- echo "⏳ Health check failed with exit code $curl_exit_code"
442- echo "Response: $health_response"
443- fi
444-
445- sleep 10
446- attempt=$((attempt + 1))
447- done
448-
449- if [ $attempt -gt $max_attempts ]; then
450- echo "❌ Health check failed after $max_attempts attempts"
376+ if ! python3 scripts/deployment_utils.py \
377+ --registry "${{ secrets.DOCKER_REGISTRY }}" \
378+ --image-name "${{ env.IMAGE_NAME }}" \
379+ --app-path "${{ secrets.STAGING_APP_PATH || '/opt/trends-earth-api-staging' }}" \
380+ health-check --port 3002 --max-attempts 30; then
381+ echo "❌ Health check failed"
451382 echo "🔍 Final debugging information:"
452383 echo " - All running containers:"
453384 docker ps --filter "name=trends-earth-staging"
0 commit comments