Skip to content

chore: upgrade to S1 Standard tier to bypass quota limits #48

chore: upgrade to S1 Standard tier to bypass quota limits

chore: upgrade to S1 Standard tier to bypass quota limits #48

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