Deploy to Production #6
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: 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 |