2025-11-12 08:17:28 -08:00
|
|
|
# Production Deployment Script for Miracles in Motion
|
|
|
|
|
# This script deploys the application to Azure with production SKUs and custom domain support
|
|
|
|
|
|
|
|
|
|
param(
|
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
|
|
|
[string]$ResourceGroupName = "rg-miraclesinmotion-prod",
|
|
|
|
|
|
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
|
|
|
[string]$Location = "East US",
|
|
|
|
|
|
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
|
|
|
[string]$CustomDomain = "mim4u.org",
|
|
|
|
|
|
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
|
|
|
[string]$StripePublicKey = "",
|
|
|
|
|
|
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
|
|
|
[switch]$SkipBuild = $false
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
Write-Host "🚀 Starting Production Deployment for Miracles in Motion" -ForegroundColor Green
|
|
|
|
|
Write-Host "=================================================" -ForegroundColor Green
|
|
|
|
|
|
|
|
|
|
# Check if Azure CLI is installed
|
|
|
|
|
if (!(Get-Command "az" -ErrorAction SilentlyContinue)) {
|
|
|
|
|
Write-Error "Azure CLI is not installed. Please install it first: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli"
|
|
|
|
|
exit 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Check if Static Web Apps CLI is installed
|
|
|
|
|
if (!(Get-Command "swa" -ErrorAction SilentlyContinue)) {
|
|
|
|
|
Write-Host "📦 Installing Azure Static Web Apps CLI..." -ForegroundColor Yellow
|
|
|
|
|
npm install -g @azure/static-web-apps-cli
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Login to Azure if not already logged in
|
|
|
|
|
$currentAccount = az account show --query "user.name" -o tsv 2>$null
|
|
|
|
|
if (!$currentAccount) {
|
|
|
|
|
Write-Host "🔐 Please log in to Azure..." -ForegroundColor Yellow
|
|
|
|
|
az login
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Write-Host "✅ Logged in as: $currentAccount" -ForegroundColor Green
|
|
|
|
|
|
|
|
|
|
# Create resource group if it doesn't exist
|
|
|
|
|
Write-Host "📁 Creating resource group: $ResourceGroupName" -ForegroundColor Yellow
|
|
|
|
|
az group create --name $ResourceGroupName --location $Location
|
|
|
|
|
|
|
|
|
|
# Validate Stripe key
|
|
|
|
|
if ([string]::IsNullOrEmpty($StripePublicKey)) {
|
|
|
|
|
$StripePublicKey = Read-Host "Enter your Stripe Public Key (pk_live_...)"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!$StripePublicKey.StartsWith("pk_live_")) {
|
|
|
|
|
Write-Warning "Warning: Using non-production Stripe key. For production, use pk_live_..."
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Build and test the application
|
|
|
|
|
if (!$SkipBuild) {
|
|
|
|
|
Write-Host "🔨 Building the application..." -ForegroundColor Yellow
|
|
|
|
|
|
|
|
|
|
# Install dependencies
|
|
|
|
|
Write-Host "📦 Installing main project dependencies..." -ForegroundColor Cyan
|
|
|
|
|
npm install --legacy-peer-deps
|
|
|
|
|
|
|
|
|
|
# Install API dependencies
|
|
|
|
|
Write-Host "📦 Installing API dependencies..." -ForegroundColor Cyan
|
|
|
|
|
Set-Location api
|
|
|
|
|
npm install
|
|
|
|
|
Set-Location ..
|
|
|
|
|
|
|
|
|
|
# Run tests
|
|
|
|
|
Write-Host "🧪 Running tests..." -ForegroundColor Cyan
|
|
|
|
|
npx vitest run --reporter=verbose
|
|
|
|
|
|
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
|
|
|
Write-Warning "Some tests failed, but continuing with deployment..."
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Build the application
|
|
|
|
|
Write-Host "🏗️ Building production bundle..." -ForegroundColor Cyan
|
|
|
|
|
npm run build
|
|
|
|
|
|
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
|
|
|
Write-Error "Build failed! Please fix the errors and try again."
|
|
|
|
|
exit 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Write-Host "✅ Build completed successfully" -ForegroundColor Green
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Deploy infrastructure
|
|
|
|
|
Write-Host "🏗️ Deploying Azure infrastructure..." -ForegroundColor Yellow
|
|
|
|
|
|
|
|
|
|
$deploymentName = "mim-prod-deployment-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
|
|
|
|
|
|
|
|
|
$deploymentResult = az deployment group create `
|
|
|
|
|
--resource-group $ResourceGroupName `
|
|
|
|
|
--template-file "infrastructure/main-production.bicep" `
|
|
|
|
|
--parameters "infrastructure/main-production.parameters.json" `
|
|
|
|
|
--parameters stripePublicKey=$StripePublicKey `
|
|
|
|
|
--parameters customDomainName=$CustomDomain `
|
|
|
|
|
--parameters enableCustomDomain=$true `
|
|
|
|
|
--name $deploymentName `
|
|
|
|
|
--output json | ConvertFrom-Json
|
|
|
|
|
|
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
|
|
|
Write-Error "Infrastructure deployment failed!"
|
|
|
|
|
exit 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Write-Host "✅ Infrastructure deployed successfully" -ForegroundColor Green
|
|
|
|
|
|
|
|
|
|
# Get deployment outputs
|
|
|
|
|
$staticWebAppName = $deploymentResult.properties.outputs.staticWebAppName.value
|
|
|
|
|
$functionAppName = $deploymentResult.properties.outputs.functionAppName.value
|
|
|
|
|
$staticWebAppUrl = $deploymentResult.properties.outputs.staticWebAppUrl.value
|
|
|
|
|
|
|
|
|
|
Write-Host "📋 Deployment Details:" -ForegroundColor Cyan
|
|
|
|
|
Write-Host " Static Web App: $staticWebAppName" -ForegroundColor White
|
|
|
|
|
Write-Host " Function App: $functionAppName" -ForegroundColor White
|
|
|
|
|
Write-Host " Primary URL: $staticWebAppUrl" -ForegroundColor White
|
|
|
|
|
if ($CustomDomain) {
|
|
|
|
|
Write-Host " Custom Domain: https://$CustomDomain" -ForegroundColor White
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Get deployment token for Static Web App
|
|
|
|
|
Write-Host "🔑 Getting deployment token..." -ForegroundColor Yellow
|
|
|
|
|
$deploymentToken = az staticwebapp secrets list --name $staticWebAppName --resource-group $ResourceGroupName --query "properties.apiKey" -o tsv
|
|
|
|
|
|
|
|
|
|
if ([string]::IsNullOrEmpty($deploymentToken)) {
|
|
|
|
|
Write-Error "Failed to get deployment token!"
|
|
|
|
|
exit 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Deploy to Static Web App
|
|
|
|
|
Write-Host "🚀 Deploying to Static Web App..." -ForegroundColor Yellow
|
|
|
|
|
|
|
|
|
|
$env:SWA_CLI_DEPLOYMENT_TOKEN = $deploymentToken
|
|
|
|
|
|
|
|
|
|
# Deploy using SWA CLI
|
|
|
|
|
swa deploy ./dist --api-location ./api --env production --deployment-token $deploymentToken
|
|
|
|
|
|
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
|
|
|
Write-Error "Static Web App deployment failed!"
|
|
|
|
|
exit 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Write-Host "✅ Application deployed successfully!" -ForegroundColor Green
|
|
|
|
|
|
|
|
|
|
# Deploy Function App
|
|
|
|
|
Write-Host "🔧 Deploying Azure Functions..." -ForegroundColor Yellow
|
|
|
|
|
|
|
|
|
|
# Build API project
|
|
|
|
|
Set-Location api
|
|
|
|
|
npm run build 2>$null
|
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
|
|
|
Write-Host "Building API project..." -ForegroundColor Cyan
|
|
|
|
|
npm run tsc 2>$null
|
|
|
|
|
}
|
|
|
|
|
Set-Location ..
|
|
|
|
|
|
|
|
|
|
# Deploy functions
|
|
|
|
|
az functionapp deployment source config-zip --resource-group $ResourceGroupName --name $functionAppName --src "./api.zip" 2>$null
|
|
|
|
|
|
|
|
|
|
if ($LASTEXITCODE -eq 0) {
|
|
|
|
|
Write-Host "✅ Azure Functions deployed successfully" -ForegroundColor Green
|
|
|
|
|
} else {
|
|
|
|
|
Write-Warning "Function deployment may have issues, but Static Web App is deployed"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Custom Domain Setup Instructions
|
|
|
|
|
if ($CustomDomain) {
|
|
|
|
|
Write-Host "🌐 Custom Domain Setup:" -ForegroundColor Magenta
|
|
|
|
|
Write-Host "================================" -ForegroundColor Magenta
|
|
|
|
|
Write-Host "1. Add a CNAME record in your DNS:" -ForegroundColor Yellow
|
|
|
|
|
Write-Host " Name: www (or @)" -ForegroundColor White
|
|
|
|
|
Write-Host " Value: $($staticWebAppUrl -replace 'https://', '')" -ForegroundColor White
|
|
|
|
|
Write-Host ""
|
|
|
|
|
Write-Host "2. Wait for DNS propagation (up to 48 hours)" -ForegroundColor Yellow
|
|
|
|
|
Write-Host "3. The SSL certificate will be automatically provisioned" -ForegroundColor Yellow
|
|
|
|
|
Write-Host ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Final Summary
|
|
|
|
|
Write-Host "🎉 DEPLOYMENT COMPLETE!" -ForegroundColor Green
|
|
|
|
|
Write-Host "========================" -ForegroundColor Green
|
|
|
|
|
Write-Host "🌐 Primary URL: $staticWebAppUrl" -ForegroundColor Cyan
|
|
|
|
|
if ($CustomDomain) {
|
|
|
|
|
Write-Host "🌐 Custom Domain: https://$CustomDomain (after DNS setup)" -ForegroundColor Cyan
|
|
|
|
|
}
|
|
|
|
|
Write-Host "🔗 Portal Access: $staticWebAppUrl#/portals" -ForegroundColor Cyan
|
|
|
|
|
Write-Host "📊 Analytics: $staticWebAppUrl#/analytics" -ForegroundColor Cyan
|
|
|
|
|
Write-Host "🤖 AI Portal: $staticWebAppUrl#/ai-portal" -ForegroundColor Cyan
|
|
|
|
|
Write-Host ""
|
|
|
|
|
Write-Host "📚 Next Steps:" -ForegroundColor Yellow
|
|
|
|
|
Write-Host "1. Set up DNS records for custom domain" -ForegroundColor White
|
|
|
|
|
Write-Host "2. Configure authentication providers if needed" -ForegroundColor White
|
|
|
|
|
Write-Host "3. Set up monitoring and alerts" -ForegroundColor White
|
|
|
|
|
Write-Host "4. Update Stripe webhook endpoints" -ForegroundColor White
|
|
|
|
|
Write-Host ""
|
2025-10-05 20:55:32 -07:00
|
|
|
Write-Host "✨ Your Miracles in Motion application is now live in production!" -ForegroundColor Green
|