Skip to main content
Glama

Carbon Voice

by PhononX
deploy-apprunner.sh13.9 kB
#!/bin/bash set -e ENVIRONMENT=$1 SERVICE_NAME=$2 LOG_LEVEL="debug" BRANCH="unknown" GITHUB_CONNECTION_ARN="arn:aws:apprunner:us-east-2:336746746018:connection/GithubPhononX/5346579f49054a59a6e309da4d0e9634" REPOSITORY_URL="https://github.com/phononx/cv-mcp-server" CARBON_VOICE_BASE_URL="https://api.carbonvoice.app" # Default service names if not provided if [ -z "$SERVICE_NAME" ]; then case $ENVIRONMENT in "dev"|"develop") SERVICE_NAME="cv-mcp-server-dev" BRANCH="develop" ;; "prod"|"production") SERVICE_NAME="cv-mcp-server-prod" BRANCH="main" ;; *) echo "Error: Unknown environment '$ENVIRONMENT'" echo "Usage: $0 <environment> [service_name]" echo "Supported environments: dev, prod" echo "Example: $0 dev" echo "Example: $0 prod cv-mcp-server-prod" exit 1 ;; esac fi if [ -z "$ENVIRONMENT" ]; then echo "Usage: $0 <environment> [service_name]" echo "Example: $0 dev" echo "Example: $0 prod cv-mcp-server-prod" exit 1 fi echo "=== 🚀 Deploying to App Runner 🚀 ===" echo "Environment: $ENVIRONMENT" echo "Service Name: $SERVICE_NAME" echo "=====================================" # Validate environment if [ "$ENVIRONMENT" != "prod" ] && [ "$ENVIRONMENT" != "dev" ] && [ "$ENVIRONMENT" != "develop" ] && [ "$ENVIRONMENT" != "production" ]; then echo "Error: Environment must be 'dev', 'develop', 'prod', or 'production'" exit 1 fi # Normalize environment if [ "$ENVIRONMENT" = "develop" ]; then ENV_CONFIG="dev" elif [ "$ENVIRONMENT" = "production" ]; then ENV_CONFIG="prod" else ENV_CONFIG="$ENVIRONMENT" fi # Set environment-specific variables if [ "$ENV_CONFIG" = "prod" ]; then ENV_VALUE="prod" # Only set LOG_LEVEL if not already defined if [ -z "$LOG_LEVEL" ]; then LOG_LEVEL="info" fi else ENV_VALUE="dev" # Only set LOG_LEVEL if not already defined if [ -z "$LOG_LEVEL" ]; then LOG_LEVEL="debug" fi fi # Verify AWS CLI is available if ! command -v aws &> /dev/null; then echo "Error: AWS CLI not found" exit 1 fi # Get service ARN echo "Looking up service ARN for $SERVICE_NAME..." SERVICE_ARN=$(aws apprunner list-services --query "ServiceSummaryList[?ServiceName=='$SERVICE_NAME'].ServiceArn" --output text) if [ -z "$SERVICE_ARN" ] || [ "$SERVICE_ARN" = "None" ]; then echo "Error: Service $SERVICE_NAME not found" echo "Available services:" aws apprunner list-services --query "ServiceSummaryList[].ServiceName" --output table exit 1 fi echo "Service ARN: $SERVICE_ARN" # Function to wait for service to be in RUNNING state wait_for_running_state() { echo "⏳ Waiting for service to be in RUNNING state..." local max_wait=900 # 15 minutes local wait_time=0 local sleep_interval=15 while [ $wait_time -lt $max_wait ]; do local current_status=$(aws apprunner describe-service --service-arn "$SERVICE_ARN" --query "Service.Status" --output text) echo "Current service status: $current_status (waited ${wait_time}s)" if [ "$current_status" = "RUNNING" ]; then echo "✅ Service is now in RUNNING state" return 0 elif [[ "$current_status" == *"FAILED"* ]]; then echo "❌ Service is in failed state: $current_status" return 1 fi sleep $sleep_interval wait_time=$((wait_time + sleep_interval)) done echo "❌ Timeout waiting for service to reach RUNNING state" return 1 } # Check current service status SERVICE_STATUS=$(aws apprunner describe-service --service-arn "$SERVICE_ARN" --query "Service.Status" --output text) echo "Current service status: $SERVICE_STATUS" # If service is not in RUNNING state, wait for it if [ "$SERVICE_STATUS" != "RUNNING" ]; then echo "Service is not in RUNNING state. Waiting before proceeding..." if ! wait_for_running_state; then exit 1 fi fi # Check if we need to update environment variables echo "🔍 Checking current environment variables..." CURRENT_ENV_VARS=$(aws apprunner describe-service --service-arn "$SERVICE_ARN" --query "Service.SourceConfiguration.CodeRepository.CodeConfiguration.CodeConfigurationValues.RuntimeEnvironmentVariables" --output json) # Get current GitHub connection ARN from authentication configuration CURRENT_GITHUB_CONNECTION_ARN=$(aws apprunner describe-service --service-arn "$SERVICE_ARN" --query "Service.SourceConfiguration.AuthenticationConfiguration.ConnectionArn" --output text) # Extract current values CURRENT_ENVIRONMENT=$(echo "$CURRENT_ENV_VARS" | jq -r '.ENVIRONMENT // "unknown"') CURRENT_LOG_LEVEL=$(echo "$CURRENT_ENV_VARS" | jq -r '.LOG_LEVEL // "unknown"') CURRENT_CARBON_VOICE_BASE_URL=$(echo "$CURRENT_ENV_VARS" | jq -r '.CARBON_VOICE_BASE_URL // "unknown"') echo "Current ENVIRONMENT: $CURRENT_ENVIRONMENT" echo "Current LOG_LEVEL: $CURRENT_LOG_LEVEL" echo "Target ENVIRONMENT: $ENV_VALUE" echo "Target LOG_LEVEL: $LOG_LEVEL" echo "Current CARBON_VOICE_BASE_URL: $CURRENT_CARBON_VOICE_BASE_URL" echo "Target CARBON_VOICE_BASE_URL: $CARBON_VOICE_BASE_URL" echo "Current GITHUB_CONNECTION_ARN: $CURRENT_GITHUB_CONNECTION_ARN" echo "Target GITHUB_CONNECTION_ARN: $GITHUB_CONNECTION_ARN" # Only update if environment variables have changed if [ "$CURRENT_ENVIRONMENT" != "$ENV_VALUE" ] || [ "$CURRENT_LOG_LEVEL" != "$LOG_LEVEL" ] || [ "$CURRENT_CARBON_VOICE_BASE_URL" != "$CARBON_VOICE_BASE_URL" ] || [ "$CURRENT_GITHUB_CONNECTION_ARN" != "$GITHUB_CONNECTION_ARN" ]; then echo "🔄 Environment variables need update. Updating service configuration..." aws apprunner update-service \ --service-arn "$SERVICE_ARN" \ --source-configuration '{ "AuthenticationConfiguration": { "ConnectionArn": "'"$GITHUB_CONNECTION_ARN"'" }, "AutoDeploymentsEnabled": false, "CodeRepository": { "RepositoryUrl": "'"$REPOSITORY_URL"'", "SourceCodeVersion": { "Type": "BRANCH", "Value": "'"$BRANCH"'" }, "CodeConfiguration": { "ConfigurationSource": "API", "CodeConfigurationValues": { "Runtime": "NODEJS_22", "BuildCommand": "npm ci && npm run build", "StartCommand": "npm run start:http", "Port": "3000", "RuntimeEnvironmentVariables": { "ENVIRONMENT": "'"$ENV_VALUE"'", "LOG_LEVEL": "'"$LOG_LEVEL"'", "LOG_TRANSPORT": "cloudwatch", "CARBON_VOICE_BASE_URL": "'"$CARBON_VOICE_BASE_URL"'" } } } } }' > /dev/null echo "✅ Environment variables updated successfully." # Wait for the update operation to complete echo "⏳ Waiting for update operation to complete..." if ! wait_for_running_state; then echo "❌ Update operation failed or timed out" exit 1 fi echo "🎉 Environment variables updated and service is ready for deployment!" else echo "✅ Environment variables are already up to date. No update needed." fi # Now start a new deployment to refresh the code echo "🚀 Starting new deployment to refresh code..." OPERATION_ID=$(aws apprunner start-deployment --service-arn "$SERVICE_ARN" --query "OperationId" --output text) if [ -z "$OPERATION_ID" ] || [ "$OPERATION_ID" = "None" ]; then echo "Error: Failed to start deployment" exit 1 fi echo "Deployment started with Operation ID: $OPERATION_ID" # Wait for deployment to complete by checking service status echo "Waiting for deployment to complete..." MAX_WAIT_TIME=1800 # 30 minutes WAIT_TIME=0 SLEEP_INTERVAL=30 while [ $WAIT_TIME -lt $MAX_WAIT_TIME ]; do # Check service status CURRENT_SERVICE_STATUS=$(aws apprunner describe-service --service-arn "$SERVICE_ARN" --query "Service.Status" --output text) echo "Service status: $CURRENT_SERVICE_STATUS (waited ${WAIT_TIME}s)" case $CURRENT_SERVICE_STATUS in "RUNNING") echo "✅ Service is running! Checking if deployment succeeded or rolled back..." # Check if our specific operation succeeded or failed OPERATION_STATUS=$(aws apprunner list-operations --service-arn "$SERVICE_ARN" --max-results 10 --query "OperationSummaryList[?Id=='$OPERATION_ID'].Status" --output text) if [ -z "$OPERATION_STATUS" ]; then echo "⚠️ Could not find operation status, checking recent operations..." RECENT_OPS=$(aws apprunner list-operations --service-arn "$SERVICE_ARN" --max-results 3 --query "OperationSummaryList[0:3].{Id:Id,Type:Type,Status:Status,StartedAt:StartedAt}" --output table) echo "Recent operations:" echo "$RECENT_OPS" # Check if the most recent operation is our deployment and if it succeeded MOST_RECENT_OP=$(aws apprunner list-operations --service-arn "$SERVICE_ARN" --max-results 1 --query "OperationSummaryList[0].{Id:Id,Status:Status}" --output json) MOST_RECENT_ID=$(echo "$MOST_RECENT_OP" | jq -r '.Id') MOST_RECENT_STATUS=$(echo "$MOST_RECENT_OP" | jq -r '.Status') if [ "$MOST_RECENT_ID" = "$OPERATION_ID" ]; then if [ "$MOST_RECENT_STATUS" = "SUCCEEDED" ]; then echo "✅ Deployment succeeded!" break elif [[ "$MOST_RECENT_STATUS" == *"ROLLBACK"* ]]; then echo "❌ Deployment failed and rolled back! Status: $MOST_RECENT_STATUS" echo "Getting recent operations for debugging:" aws apprunner list-operations --service-arn "$SERVICE_ARN" --max-results 5 --output table exit 1 else echo "❌ Deployment failed with status: $MOST_RECENT_STATUS" exit 1 fi else echo "⚠️ Most recent operation ID doesn't match our deployment. Assuming success since service is running." break fi else echo "Operation status: $OPERATION_STATUS" if [ "$OPERATION_STATUS" = "SUCCEEDED" ]; then echo "✅ Deployment succeeded!" break elif [[ "$OPERATION_STATUS" == *"ROLLBACK"* ]]; then echo "❌ Deployment failed and rolled back! Status: $OPERATION_STATUS" echo "Getting recent operations for debugging:" aws apprunner list-operations --service-arn "$SERVICE_ARN" --max-results 5 --output table exit 1 else echo "❌ Deployment failed with status: $OPERATION_STATUS" exit 1 fi fi ;; "OPERATION_IN_PROGRESS") echo "⏳ Deployment still in progress..." ;; "CREATE_FAILED"|"UPDATE_FAILED"|"DELETE_FAILED") echo "❌ Deployment failed with status: $CURRENT_SERVICE_STATUS" # Get recent operations for debugging echo "Recent operations for debugging:" aws apprunner list-operations --service-arn "$SERVICE_ARN" --max-results 3 --output table exit 1 ;; *) echo "⚠️ Service status: $CURRENT_SERVICE_STATUS" ;; esac sleep $SLEEP_INTERVAL WAIT_TIME=$((WAIT_TIME + SLEEP_INTERVAL)) done if [ $WAIT_TIME -ge $MAX_WAIT_TIME ]; then echo "❌ Deployment monitoring timed out after $MAX_WAIT_TIME seconds" echo "Service may still be deploying. Check AWS Console for current status." exit 1 fi # Get service information echo "=== Deployment Summary ===" SERVICE_INFO=$(aws apprunner describe-service --service-arn "$SERVICE_ARN") SERVICE_URL=$(echo "$SERVICE_INFO" | jq -r '.Service.ServiceUrl') SERVICE_STATUS=$(echo "$SERVICE_INFO" | jq -r '.Service.Status') CREATED_AT=$(echo "$SERVICE_INFO" | jq -r '.Service.CreatedAt') UPDATED_AT=$(echo "$SERVICE_INFO" | jq -r '.Service.UpdatedAt') echo "Service Name: $SERVICE_NAME" echo "Environment: $ENVIRONMENT" echo "Status: $SERVICE_STATUS" echo "Service URL: https://$SERVICE_URL" echo "Created At: $CREATED_AT" echo "Updated At: $UPDATED_AT" echo "===========================" # Test health endpoint echo "Testing health endpoint..." if command -v curl &> /dev/null; then sleep 10 # Give the service a moment to be ready HEALTH_URL="https://$SERVICE_URL/health" for i in {1..5}; do echo "Health check attempt $i/5..." if curl -f -s "$HEALTH_URL" > /dev/null; then echo "✅ Health check passed!" break else echo "⚠️ Health check failed, retrying in 10s..." sleep 10 fi if [ $i -eq 5 ]; then echo "❌ Health check failed after 5 attempts" echo "Please verify the service manually: $HEALTH_URL" fi done else echo "⚠️ curl not available, skipping health check" echo "Please verify manually: https://$SERVICE_URL/health" fi echo "🚀 Deployment completed successfully!" echo "Service URL: https://$SERVICE_URL"

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/PhononX/cv-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server