Skip to content

Deploy to Production #6

Deploy to Production

Deploy to Production #6

name: Deploy to Production
on:
workflow_dispatch:
inputs:
services:
description: 'Services to deploy'
required: true
default: 'all'
type: choice
options:
- all
- frontend
- user_service
- appointment_service
- service_management
- staff_management
- notification_service
- reports_analytics
image_source:
description: 'Image source'
required: true
default: 'promote-staging'
type: choice
options:
- promote-staging
- specific-tag
specific_tag:
description: 'Specific image tag (only if "specific-tag" selected)'
required: false
type: string
confirm_deployment:
description: 'Type "DEPLOY" to confirm production deployment'
required: true
type: string
env:
AWS_REGION: us-east-1
ECR_REGISTRY: '024955634588.dkr.ecr.us-east-1.amazonaws.com'
jobs:
validate:
name: Validate Request
runs-on: ubuntu-latest
outputs:
services: ${{ steps.parse.outputs.services }}
steps:
- name: Verify confirmation
if: ${{ github.event.inputs.confirm_deployment != 'DEPLOY' }}
run: |
echo "::error::Deployment not confirmed. Type 'DEPLOY' to confirm."
exit 1
- name: Parse services
id: parse
run: |
INPUT="${{ github.event.inputs.services }}"
if [ "$INPUT" == "all" ]; then
SERVICES="frontend user_service appointment_service service_management staff_management notification_service reports_analytics"
else
SERVICES="$INPUT"
fi
echo "Services to deploy: $SERVICES"
echo "services=$SERVICES" >> $GITHUB_OUTPUT
deploy:
name: Deploy Services
runs-on: ubuntu-latest
needs: [validate]
environment: production
steps:
- name: Checkout GitOps repo
uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Deploy all services
run: |
SERVICES="${{ needs.validate.outputs.services }}"
IMAGE_SOURCE="${{ github.event.inputs.image_source }}"
SPECIFIC_TAG="${{ github.event.inputs.specific_tag }}"
echo "## Production Deployment" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Service | Previous Tag | New Tag | Status |" >> $GITHUB_STEP_SUMMARY
echo "|---------|--------------|---------|--------|" >> $GITHUB_STEP_SUMMARY
FAILED=0
for SERVICE in $SERVICES; do
echo "=========================================="
echo "Processing: $SERVICE"
echo "=========================================="
STAGING_FILE="staging/${SERVICE}/deployment.yaml"
PROD_FILE="production/${SERVICE}/deployment.yaml"
# Get the tag to deploy
if [ "$IMAGE_SOURCE" == "specific-tag" ] && [ -n "$SPECIFIC_TAG" ]; then
NEW_TAG="$SPECIFIC_TAG"
else
# Get tag from staging deployment
if [ ! -f "$STAGING_FILE" ]; then
echo "::warning::Staging file not found: $STAGING_FILE"
echo "| $SERVICE | - | - | SKIP (no staging) |" >> $GITHUB_STEP_SUMMARY
continue
fi
STAGING_TAG=$(grep "image:" "$STAGING_FILE" | head -1 | awk -F: '{print $NF}' | tr -d ' ')
# For frontend: staging image has "staging-" prefix, production doesn't
# staging-abc12345-20251215 -> abc12345-20251215
if [ "$SERVICE" == "frontend" ]; then
NEW_TAG=$(echo "$STAGING_TAG" | sed 's/^staging-//')
else
NEW_TAG="$STAGING_TAG"
fi
fi
echo "Tag to deploy: $NEW_TAG"
# Verify image exists in ECR
if ! aws ecr describe-images \
--repository-name "$SERVICE" \
--image-ids imageTag="$NEW_TAG" \
--region ${{ env.AWS_REGION }} > /dev/null 2>&1; then
echo "::error::Image not found in ECR: $SERVICE:$NEW_TAG"
echo "| $SERVICE | - | $NEW_TAG | FAILED (not in ECR) |" >> $GITHUB_STEP_SUMMARY
FAILED=1
continue
fi
# Check production file exists
if [ ! -f "$PROD_FILE" ]; then
echo "::warning::Production file not found: $PROD_FILE"
echo "| $SERVICE | - | - | SKIP (no prod file) |" >> $GITHUB_STEP_SUMMARY
continue
fi
# Get current production tag
CURRENT_TAG=$(grep "image:" "$PROD_FILE" | head -1 | awk -F: '{print $NF}' | tr -d ' ')
# Update production deployment
sed -i "s|image: ${{ env.ECR_REGISTRY }}/${SERVICE}:.*|image: ${{ env.ECR_REGISTRY }}/${SERVICE}:${NEW_TAG}|g" "$PROD_FILE"
echo "Updated: $CURRENT_TAG -> $NEW_TAG"
echo "| $SERVICE | \`$CURRENT_TAG\` | \`$NEW_TAG\` | OK |" >> $GITHUB_STEP_SUMMARY
done
if [ $FAILED -eq 1 ]; then
echo "::error::Some services failed validation"
exit 1
fi
- name: Commit and push changes
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add -A
if git diff --staged --quiet; then
echo "No changes to commit"
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Result:** No changes needed" >> $GITHUB_STEP_SUMMARY
else
SERVICES="${{ needs.validate.outputs.services }}"
git commit -m "[PRODUCTION] Deploy: $SERVICES - by ${{ github.actor }} - run ${{ github.run_id }}"
git push
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Result:** Successfully pushed to GitOps repo" >> $GITHUB_STEP_SUMMARY
fi
- name: Deployment complete
run: |
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Next Steps" >> $GITHUB_STEP_SUMMARY
echo "1. ArgoCD will auto-sync within 3 minutes" >> $GITHUB_STEP_SUMMARY
echo "2. Monitor: https://argocd.aurora-glam.com" >> $GITHUB_STEP_SUMMARY
echo "3. Verify: https://aurora-glam.com" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "---" >> $GITHUB_STEP_SUMMARY
echo "**Deployed by:** ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "**Timestamp:** $(date -u)" >> $GITHUB_STEP_SUMMARY