chore: upgrade to S1 Standard tier to bypass quota limits #48
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 Team-Boost Infrastructure and Application | |
| # NOTE: Auto-deploy disabled until Azure quota is approved. | |
| # To re-enable, uncomment the push and pull_request triggers below. | |
| on: | |
| push: | |
| branches: [ main, dev ] | |
| paths: | |
| - 'infrastructure/**' | |
| - '.github/workflows/deploy-infrastructure.yml' | |
| - 'app/**' | |
| - 'public/**' | |
| - 'package.json' | |
| - 'next.config.js' | |
| # pull_request: | |
| # branches: [ main, dev ] | |
| # paths: | |
| # - 'infrastructure/**' | |
| # - '.github/workflows/deploy-infrastructure.yml' | |
| workflow_dispatch: | |
| inputs: | |
| environment: | |
| description: 'Environment to deploy' | |
| required: true | |
| default: 'development' | |
| type: choice | |
| options: | |
| - development | |
| - production | |
| permissions: | |
| id-token: write | |
| contents: read | |
| env: | |
| AZURE_RESOURCE_GROUP_DEV: teamboost-rg-dev | |
| AZURE_RESOURCE_GROUP_PROD: teamboost-rg-prod | |
| AZURE_LOCATION: East US | |
| jobs: | |
| # validate: | |
| # name: Validate Infrastructure Templates | |
| # runs-on: ubuntu-latest | |
| # | |
| # steps: | |
| # - name: Checkout Team-Boost code | |
| # uses: actions/checkout@v4 | |
| # | |
| # - name: Azure Login | |
| # uses: azure/login@v1 | |
| # with: | |
| # client-id: ${{ secrets.AZURE_CLIENT_ID }} | |
| # tenant-id: ${{ secrets.AZURE_TENANT_ID }} | |
| # subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} | |
| # | |
| # - name: Internal Validate | |
| # run: | | |
| # echo "Validation skipped due to Quota limits." | |
| # # az deployment group validate ... | |
| deploy-dev: | |
| name: Deploy to Development | |
| runs-on: ubuntu-latest | |
| # needs: validate # Skipped due to Azure Quota false positives on validation | |
| if: github.ref == 'refs/heads/dev' && github.event_name == 'push' | |
| environment: development | |
| steps: | |
| - name: Checkout Team-Boost code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js 20 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| - name: Azure Login | |
| uses: azure/login@v1 | |
| with: | |
| client-id: ${{ secrets.AZURE_CLIENT_ID }} | |
| tenant-id: ${{ secrets.AZURE_TENANT_ID }} | |
| subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} | |
| - name: Create Resource Group | |
| run: | | |
| az group create \ | |
| --name ${{ env.AZURE_RESOURCE_GROUP_DEV }} \ | |
| --location "${{ env.AZURE_LOCATION }}" \ | |
| --tags Environment=dev Application=team-boost ManagedBy=GitHub-Actions | |
| - name: Deploy Infrastructure | |
| id: deploy-infra | |
| run: | | |
| cd infrastructure/bicep | |
| echo "=== DEBUG: FILE CONTENT ===" | |
| ls -la | |
| grep "cosmosContainerName" main.bicep | |
| grep "excludedPaths" main.bicep -A 5 | |
| echo "===========================" | |
| DEPLOYMENT_NAME="teamboost-dev-deployment-$(date +%Y%m%d-%H%M%S)" | |
| az deployment group create \ | |
| --resource-group ${{ env.AZURE_RESOURCE_GROUP_DEV }} \ | |
| --template-file main.bicep \ | |
| --parameters @parameters.dev.json \ | |
| --parameters tenantId=${{ secrets.AZURE_TENANT_ID }} \ | |
| --parameters clientId=${{ secrets.TEAMBOOST_CLIENT_ID }} \ | |
| --name $DEPLOYMENT_NAME | |
| # Get outputs | |
| WEB_APP_URL=$(az deployment group show \ | |
| --resource-group ${{ env.AZURE_RESOURCE_GROUP_DEV }} \ | |
| --name $DEPLOYMENT_NAME \ | |
| --query "properties.outputs.webAppUrl.value" -o tsv) | |
| WEB_APP_NAME=$(az deployment group show \ | |
| --resource-group ${{ env.AZURE_RESOURCE_GROUP_DEV }} \ | |
| --name $DEPLOYMENT_NAME \ | |
| --query "properties.outputs.webAppName.value" -o tsv) | |
| KEY_VAULT_NAME=$(az deployment group show \ | |
| --resource-group ${{ env.AZURE_RESOURCE_GROUP_DEV }} \ | |
| --name $DEPLOYMENT_NAME \ | |
| --query "properties.outputs.keyVaultName.value" -o tsv) | |
| echo "web-app-url=$WEB_APP_URL" >> $GITHUB_OUTPUT | |
| echo "web-app-name=$WEB_APP_NAME" >> $GITHUB_OUTPUT | |
| echo "key-vault-name=$KEY_VAULT_NAME" >> $GITHUB_OUTPUT | |
| - name: Manage Auth Secrets | |
| env: | |
| AZURE_KEY_VAULT_NAME: ${{ steps.deploy-infra.outputs.key-vault-name }} | |
| TEAMBOOST_CLIENT_ID: ${{ secrets.TEAMBOOST_CLIENT_ID }} | |
| run: | | |
| chmod +x infrastructure/scripts/manage-auth-secrets.sh | |
| ./infrastructure/scripts/manage-auth-secrets.sh | |
| - name: Install Dependencies | |
| run: | | |
| npm ci --legacy-peer-deps | |
| - name: Build and Deploy Team-Boost Application | |
| env: | |
| NODE_ENV: production | |
| ENVIRONMENT: dev | |
| run: | | |
| # Build the Team-Boost application | |
| npm run build | |
| # Create deployment package for Next.js 16 App Router | |
| mkdir -p deployment | |
| # Copy Next.js build output | |
| if [[ -d ".next/standalone" ]]; then | |
| # Standalone build (preferred for App Service) | |
| cp -r .next/standalone/. deployment/ | |
| mkdir -p deployment/.next/static && cp -r .next/static/* deployment/.next/static/ | |
| else | |
| # Standard build fallback | |
| cp -r .next deployment/ | |
| cp package*.json deployment/ | |
| fi | |
| # Copy public assets and config | |
| [[ -d "public" ]] && cp -r public deployment/ | |
| [[ -f "next.config.js" ]] && cp next.config.js deployment/ | |
| # Create startup script | |
| cat > deployment/startup.sh << 'EOF' | |
| #!/bin/bash | |
| cd /home/site/wwwroot | |
| if [ -f "server.js" ]; then | |
| node server.js | |
| else | |
| npm install --production | |
| npm start | |
| fi | |
| EOF | |
| chmod +x deployment/startup.sh | |
| # Create ZIP for deployment | |
| cd deployment | |
| zip -r ../teamboost-app.zip . > /dev/null | |
| cd .. | |
| # Start the webapp in case it was stopped | |
| az webapp start \ | |
| --resource-group ${{ env.AZURE_RESOURCE_GROUP_DEV }} \ | |
| --name ${{ steps.deploy-infra.outputs.web-app-name }} || true | |
| # Deploy to App Service | |
| az webapp deployment source config-zip \ | |
| --resource-group ${{ env.AZURE_RESOURCE_GROUP_DEV }} \ | |
| --name ${{ steps.deploy-infra.outputs.web-app-name }} \ | |
| --src teamboost-app.zip | |
| - name: Display Deployment Info | |
| run: | | |
| echo "🚀 Team-Boost Development deployment completed!" | |
| echo "Web App URL: ${{ steps.deploy-infra.outputs.web-app-url }}" | |
| echo "App Service: ${{ steps.deploy-infra.outputs.web-app-name }}" | |
| echo "Key Vault: ${{ steps.deploy-infra.outputs.key-vault-name }}" | |
| echo "" | |
| echo "📋 Next steps:" | |
| echo "1. Update your Microsoft Entra ID app registration:" | |
| echo " - Redirect URI: ${{ steps.deploy-infra.outputs.web-app-url }}/api/auth/callback/microsoft-entra-id" | |
| echo " - Logout URL: ${{ steps.deploy-infra.outputs.web-app-url }}" | |
| echo "2. Test the Team-Boost application and authentication flow" | |
| deploy-prod: | |
| name: Deploy to Production | |
| runs-on: ubuntu-latest | |
| # needs: validate # Skipped due to Azure Quota false positives | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| environment: production | |
| steps: | |
| - name: Checkout Team-Boost code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js 20 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| - name: Azure Login | |
| uses: azure/login@v1 | |
| with: | |
| client-id: ${{ secrets.AZURE_CLIENT_ID }} | |
| tenant-id: ${{ secrets.AZURE_TENANT_ID }} | |
| subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} | |
| - name: Create Resource Group | |
| run: | | |
| az group create \ | |
| --name ${{ env.AZURE_RESOURCE_GROUP_PROD }} \ | |
| --location "${{ env.AZURE_LOCATION }}" \ | |
| --tags Environment=prod Application=team-boost ManagedBy=GitHub-Actions | |
| - name: Deploy Infrastructure | |
| id: deploy-infra | |
| run: | | |
| cd infrastructure/bicep | |
| DEPLOYMENT_NAME="teamboost-prod-deployment-$(date +%Y%m%d-%H%M%S)" | |
| az deployment group create \ | |
| --resource-group ${{ env.AZURE_RESOURCE_GROUP_PROD }} \ | |
| --template-file main.bicep \ | |
| --parameters @parameters.prod.json \ | |
| --parameters tenantId=${{ secrets.AZURE_TENANT_ID }} \ | |
| --parameters clientId=${{ secrets.TEAMBOOST_CLIENT_ID }} \ | |
| --name $DEPLOYMENT_NAME | |
| # Get outputs | |
| WEB_APP_URL=$(az deployment group show \ | |
| --resource-group ${{ env.AZURE_RESOURCE_GROUP_PROD }} \ | |
| --name $DEPLOYMENT_NAME \ | |
| --query "properties.outputs.webAppUrl.value" -o tsv) | |
| WEB_APP_NAME=$(az deployment group show \ | |
| --resource-group ${{ env.AZURE_RESOURCE_GROUP_PROD }} \ | |
| --name $DEPLOYMENT_NAME \ | |
| --query "properties.outputs.webAppName.value" -o tsv) | |
| KEY_VAULT_NAME=$(az deployment group show \ | |
| --resource-group ${{ env.AZURE_RESOURCE_GROUP_PROD }} \ | |
| --name $DEPLOYMENT_NAME \ | |
| --query "properties.outputs.keyVaultName.value" -o tsv) | |
| echo "web-app-url=$WEB_APP_URL" >> $GITHUB_OUTPUT | |
| echo "web-app-name=$WEB_APP_NAME" >> $GITHUB_OUTPUT | |
| echo "key-vault-name=$KEY_VAULT_NAME" >> $GITHUB_OUTPUT | |
| - name: Manage Auth Secrets | |
| env: | |
| AZURE_KEY_VAULT_NAME: ${{ steps.deploy-infra.outputs.key-vault-name }} | |
| TEAMBOOST_CLIENT_ID: ${{ secrets.TEAMBOOST_CLIENT_ID }} | |
| run: | | |
| chmod +x infrastructure/scripts/manage-auth-secrets.sh | |
| ./infrastructure/scripts/manage-auth-secrets.sh | |
| - name: Install Dependencies | |
| run: | | |
| npm ci --legacy-peer-deps | |
| - name: Build and Deploy Team-Boost Application | |
| env: | |
| NODE_ENV: production | |
| ENVIRONMENT: prod | |
| run: | | |
| # Build the Team-Boost application | |
| npm run build | |
| # Create deployment package for Next.js 16 App Router | |
| mkdir -p deployment | |
| # Copy Next.js build output | |
| if [[ -d ".next/standalone" ]]; then | |
| # Standalone build (preferred for App Service) | |
| cp -r .next/standalone/. deployment/ | |
| mkdir -p deployment/.next/static && cp -r .next/static/* deployment/.next/static/ | |
| else | |
| # Standard build fallback | |
| cp -r .next deployment/ | |
| cp package*.json deployment/ | |
| fi | |
| # Copy public assets and config | |
| [[ -d "public" ]] && cp -r public deployment/ | |
| [[ -f "next.config.js" ]] && cp next.config.js deployment/ | |
| # Create startup script | |
| cat > deployment/startup.sh << 'EOF' | |
| #!/bin/bash | |
| cd /home/site/wwwroot | |
| if [ -f "server.js" ]; then | |
| node server.js | |
| else | |
| npm install --production | |
| npm start | |
| fi | |
| EOF | |
| chmod +x deployment/startup.sh | |
| # Create ZIP for deployment | |
| cd deployment | |
| zip -r ../teamboost-app.zip . > /dev/null | |
| cd .. | |
| # Start the webapp in case it was stopped | |
| az webapp start \ | |
| --resource-group ${{ env.AZURE_RESOURCE_GROUP_PROD }} \ | |
| --name ${{ steps.deploy-infra.outputs.web-app-name }} || true | |
| # Deploy to App Service | |
| az webapp deployment source config-zip \ | |
| --resource-group ${{ env.AZURE_RESOURCE_GROUP_PROD }} \ | |
| --name ${{ steps.deploy-infra.outputs.web-app-name }} \ | |
| --src teamboost-app.zip | |
| - name: Display Deployment Info | |
| run: | | |
| echo "🚀 Team-Boost Production deployment completed!" | |
| echo "Web App URL: ${{ steps.deploy-infra.outputs.web-app-url }}" | |
| echo "App Service: ${{ steps.deploy-infra.outputs.web-app-name }}" | |
| echo "Key Vault: ${{ steps.deploy-infra.outputs.key-vault-name }}" | |
| echo "" | |
| echo "📋 Production checklist:" | |
| echo "1. Update Microsoft Entra ID app registration with production URLs" | |
| echo "2. Configure custom domain if needed" | |
| echo "3. Set up monitoring alerts" | |
| echo "4. Test all Team-Boost features in production" | |
| manual-deploy: | |
| name: Manual Environment Deploy | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'workflow_dispatch' | |
| environment: ${{ github.event.inputs.environment }} | |
| steps: | |
| - name: Checkout Team-Boost code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js 20 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| - name: Azure Login | |
| uses: azure/login@v1 | |
| with: | |
| client-id: ${{ secrets.AZURE_CLIENT_ID }} | |
| tenant-id: ${{ secrets.AZURE_TENANT_ID }} | |
| subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} | |
| - name: Set Environment Variables | |
| run: | | |
| if [[ "${{ github.event.inputs.environment }}" == "production" ]]; then | |
| echo "RESOURCE_GROUP=${{ env.AZURE_RESOURCE_GROUP_PROD }}" >> $GITHUB_ENV | |
| echo "ENV_SHORT=prod" >> $GITHUB_ENV | |
| else | |
| echo "RESOURCE_GROUP=${{ env.AZURE_RESOURCE_GROUP_DEV }}" >> $GITHUB_ENV | |
| echo "ENV_SHORT=dev" >> $GITHUB_ENV | |
| fi | |
| - name: Deploy Infrastructure | |
| id: deploy-infra | |
| run: | | |
| cd infrastructure/bicep | |
| DEPLOYMENT_NAME="teamboost-${{ env.ENV_SHORT }}-deployment-$(date +%Y%m%d-%H%M%S)" | |
| az deployment group create \ | |
| --resource-group ${{ env.RESOURCE_GROUP }} \ | |
| --template-file main.bicep \ | |
| --parameters @parameters.${{ env.ENV_SHORT }}.json \ | |
| --parameters tenantId=${{ secrets.AZURE_TENANT_ID }} \ | |
| --parameters clientId=${{ secrets.TEAMBOOST_CLIENT_ID }} \ | |
| --name $DEPLOYMENT_NAME | |
| # Get outputs | |
| WEB_APP_URL=$(az deployment group show \ | |
| --resource-group ${{ env.RESOURCE_GROUP }} \ | |
| --name $DEPLOYMENT_NAME \ | |
| --query "properties.outputs.webAppUrl.value" -o tsv) | |
| WEB_APP_NAME=$(az deployment group show \ | |
| --resource-group ${{ env.RESOURCE_GROUP }} \ | |
| --name $DEPLOYMENT_NAME \ | |
| --query "properties.outputs.webAppName.value" -o tsv) | |
| KEY_VAULT_NAME=$(az deployment group show \ | |
| --resource-group ${{ env.RESOURCE_GROUP }} \ | |
| --name $DEPLOYMENT_NAME \ | |
| --query "properties.outputs.keyVaultName.value" -o tsv) | |
| echo "web-app-url=$WEB_APP_URL" >> $GITHUB_OUTPUT | |
| echo "web-app-name=$WEB_APP_NAME" >> $GITHUB_OUTPUT | |
| echo "key-vault-name=$KEY_VAULT_NAME" >> $GITHUB_OUTPUT | |
| - name: Assign Key Vault Permissions | |
| run: | | |
| # Get the Object ID of the Service Principal | |
| SP_OBJECT_ID=$(az ad sp show --id ${{ secrets.AZURE_CLIENT_ID }} --query id -o tsv) | |
| # Assign Key Vault Secrets Officer role | |
| az role assignment create \ | |
| --role "Key Vault Secrets Officer" \ | |
| --assignee-object-id $SP_OBJECT_ID \ | |
| --scope "/subscriptions/${{ secrets.AZURE_SUBSCRIPTION_ID }}/resourceGroups/${{ env.RESOURCE_GROUP }}/providers/Microsoft.KeyVault/vaults/${{ steps.deploy-infra.outputs.key-vault-name }}" \ | |
| --assignee-principal-type ServicePrincipal \ | |
| || echo "Role assignment might already exist" | |
| # Wait for propagation | |
| sleep 15 | |
| - name: Manage Auth Secrets | |
| env: | |
| AZURE_KEY_VAULT_NAME: ${{ steps.deploy-infra.outputs.key-vault-name }} | |
| TEAMBOOST_CLIENT_ID: ${{ secrets.TEAMBOOST_CLIENT_ID }} | |
| run: | | |
| chmod +x infrastructure/scripts/manage-auth-secrets.sh | |
| ./infrastructure/scripts/manage-auth-secrets.sh | |
| - name: Install Dependencies | |
| run: | | |
| npm ci --legacy-peer-deps | |
| - name: Build and Deploy Application | |
| env: | |
| NODE_ENV: production | |
| ENVIRONMENT: ${{ env.ENV_SHORT }} | |
| run: | | |
| npm run build | |
| # Deployment package logic | |
| mkdir -p deployment | |
| if [[ -d ".next/standalone" ]]; then | |
| cp -r .next/standalone/. deployment/ | |
| mkdir -p deployment/.next/static && cp -r .next/static/* deployment/.next/static/ | |
| else | |
| cp -r .next deployment/ | |
| cp package*.json deployment/ | |
| fi | |
| [[ -d "public" ]] && cp -r public deployment/ | |
| [[ -f "next.config.js" ]] && cp next.config.js deployment/ | |
| # Startup script | |
| cat > deployment/startup.sh << 'EOF' | |
| #!/bin/bash | |
| cd /home/site/wwwroot | |
| if [ -f "server.js" ]; then | |
| node server.js | |
| else | |
| npm install --production | |
| npm start | |
| fi | |
| EOF | |
| chmod +x deployment/startup.sh | |
| # Zip and deploy | |
| cd deployment | |
| zip -r ../teamboost-app.zip . > /dev/null | |
| cd .. | |
| # Start the webapp in case it was stopped | |
| az webapp start \ | |
| --resource-group ${{ env.RESOURCE_GROUP }} \ | |
| --name ${{ steps.deploy-infra.outputs.web-app-name }} || true | |
| az webapp deployment source config-zip \ | |
| --resource-group ${{ env.RESOURCE_GROUP }} \ | |
| --name ${{ steps.deploy-infra.outputs.web-app-name }} \ | |
| --src teamboost-app.zip |