diff --git a/.github/workflows/deploy-Parameterized.yml b/.github/workflows/deploy-Parameterized.yml
new file mode 100644
index 000000000..bbb769b48
--- /dev/null
+++ b/.github/workflows/deploy-Parameterized.yml
@@ -0,0 +1,625 @@
+name: Deploy-Test-Cleanup (Parameterized)
+on:
+ pull_request:
+ branches:
+ - main
+ workflow_run:
+ workflows: ["Build Docker and Optional Push"]
+ types:
+ - completed
+ branches:
+ - main
+ - dev
+ - demo
+ workflow_dispatch:
+ inputs:
+ run_e2e_tests:
+ description: 'Run end-to-end tests'
+ required: false
+ default: true
+ type: boolean
+ cleanup_resources:
+ description: 'Cleanup deployed resources'
+ required: false
+ default: false
+ type: boolean
+ waf_enabled:
+ description: 'Enable WAF'
+ required: false
+ default: false
+ type: boolean
+ EXP:
+ description: 'Enable EXP'
+ required: false
+ default: false
+ type: boolean
+ AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID:
+ description: 'Log Analytics Workspace ID (optional)'
+ required: false
+ default: ''
+ type: string
+ AZURE_EXISTING_AI_PROJECT_RESOURCE_ID:
+ description: 'AI Project Resource ID (optional)'
+ required: false
+ default: ''
+ type: string
+ existing_webapp_url:
+ description: 'Existing WebApp URL'
+ required: false
+ default: ''
+ type: string
+ build_docker_image:
+ description: 'Build and push Docker image'
+ required: false
+ default: false
+ type: boolean
+ schedule:
+ - cron: "0 6,18 * * *" # Runs at 6:00 AM and 6:00 PM GMT
+
+
+
+env:
+ GPT_MIN_CAPACITY: 150
+ TEXT_EMBEDDING_MIN_CAPACITY: 80
+ BRANCH_NAME: ${{ github.event.workflow_run.head_branch || github.head_ref || github.ref_name }}
+ # For automatic triggers (pull_request, workflow_run, schedule): force Non-WAF + Non-EXP
+ # For manual dispatch: use input values or defaults
+ WAF_ENABLED: ${{ github.event_name == 'workflow_dispatch' && (github.event.inputs.waf_enabled || false) || false }}
+ EXP: ${{ github.event_name == 'workflow_dispatch' && (github.event.inputs.EXP || false) || false }}
+ CLEANUP_RESOURCES: ${{ github.event_name == 'workflow_dispatch' && (github.event.inputs.cleanup_resources || true) || true }}
+ RUN_E2E_TESTS: ${{ github.event_name == 'workflow_dispatch' && (github.event.inputs.run_e2e_tests || true) || true }}
+ BUILD_DOCKER_IMAGE: ${{ github.event_name == 'workflow_dispatch' && (github.event.inputs.build_docker_image || false) || false }}
+
+jobs:
+ deploy:
+ # Skip deployment if an existing webapp URL is provided
+ if: github.event_name != 'workflow_dispatch' || github.event.inputs.existing_webapp_url == '' || github.event.inputs.existing_webapp_url == null
+ runs-on: ubuntu-latest
+ outputs:
+ RESOURCE_GROUP_NAME: ${{ steps.check_create_rg.outputs.RESOURCE_GROUP_NAME }}
+ WEBAPP_URL: ${{ steps.get_output.outputs.WEBAPP_URL }}
+ ENV_NAME: ${{ steps.generate_env_name.outputs.ENV_NAME }}
+ AZURE_LOCATION: ${{ steps.set_region.outputs.AZURE_LOCATION }}
+ IMAGE_TAG: ${{ steps.generate_docker_tag.outputs.IMAGE_TAG }}
+ env:
+ # For automatic triggers: force Non-WAF + Non-EXP, for manual dispatch: use inputs
+ WAF_ENABLED: ${{ github.event_name == 'workflow_dispatch' && (github.event.inputs.waf_enabled || false) || false }}
+ EXP: ${{ github.event_name == 'workflow_dispatch' && (github.event.inputs.EXP || false) || false }}
+ CLEANUP_RESOURCES: ${{ github.event_name == 'workflow_dispatch' && (github.event.inputs.cleanup_resources || true) || true }}
+
+ steps:
+ - name: Display Workflow Configuration
+ run: |
+ echo "đ ==================================="
+ echo "đ WORKFLOW CONFIGURATION SUMMARY"
+ echo "đ ==================================="
+ echo "Trigger Type: ${{ github.event_name }}"
+ echo "Branch: ${{ env.BRANCH_NAME }}"
+ echo ""
+ echo "Configuration Settings:"
+ echo " âĸ WAF Enabled: ${{ env.WAF_ENABLED }}"
+ echo " âĸ EXP Enabled: ${{ env.EXP }}"
+ echo " âĸ Run E2E Tests: ${{ env.RUN_E2E_TESTS }}"
+ echo " âĸ Cleanup Resources: ${{ env.CLEANUP_RESOURCES }}"
+ echo " âĸ Build Docker Image: ${{ env.BUILD_DOCKER_IMAGE }}"
+ if [[ "${{ github.event.inputs.existing_webapp_url }}" != "" ]]; then
+ echo " âĸ Using Existing Webapp URL: ${{ github.event.inputs.existing_webapp_url }}"
+ echo " âĸ Skip Deployment: Yes"
+ else
+ echo " âĸ Skip Deployment: No"
+ fi
+ echo ""
+ if [[ "${{ github.event_name }}" != "workflow_dispatch" ]]; then
+ echo "âšī¸ Automatic Trigger: Using Non-WAF + Non-EXP configuration"
+ else
+ echo "âšī¸ Manual Trigger: Using user-specified configuration"
+ # Check if EXP was auto-enabled after user input validation
+ if [[ "${{ env.EXP }}" == "true" && "${{ github.event.inputs.EXP }}" != "true" ]]; then
+ echo "đ§ Note: EXP was automatically enabled due to provided parameter values"
+ fi
+ fi
+ echo "đ ==================================="
+
+ - name: Validate and Auto-Configure EXP
+ run: |
+ echo "đ Validating EXP configuration..."
+
+ # Check if EXP values were provided but EXP is disabled
+ if [[ "${{ github.event.inputs.EXP }}" != "true" ]]; then
+ if [[ -n "${{ github.event.inputs.AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID }}" ]] || [[ -n "${{ github.event.inputs.AZURE_EXISTING_AI_PROJECT_RESOURCE_ID }}" ]]; then
+ echo "đ§ AUTO-ENABLING EXP: EXP parameter values were provided but EXP was not explicitly enabled."
+ echo ""
+ echo "You provided values for:"
+ [[ -n "${{ github.event.inputs.AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID }}" ]] && echo " - Azure Log Analytics Workspace ID: '${{ github.event.inputs.AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID }}'"
+ [[ -n "${{ github.event.inputs.AZURE_EXISTING_AI_PROJECT_RESOURCE_ID }}" ]] && echo " - Azure AI Project Resource ID: '${{ github.event.inputs.AZURE_EXISTING_AI_PROJECT_RESOURCE_ID }}'"
+ echo ""
+ echo "â
Automatically enabling EXP to use these values."
+ echo "EXP=true" >> $GITHUB_ENV
+ echo "đ EXP has been automatically enabled for this deployment."
+ fi
+ fi
+
+ echo "â
EXP configuration is valid"
+
+ - name: Checkout Code
+ uses: actions/checkout@v4
+
+ - name: Setup Azure CLI
+ run: |
+ curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
+ az --version # Verify installation
+
+ - name: Run Quota Check
+ id: quota-check
+ run: |
+ export AZURE_CLIENT_ID=${{ secrets.AZURE_CLIENT_ID }}
+ export AZURE_TENANT_ID=${{ secrets.AZURE_TENANT_ID }}
+ export AZURE_CLIENT_SECRET=${{ secrets.AZURE_CLIENT_SECRET }}
+ export AZURE_SUBSCRIPTION_ID="${{ secrets.AZURE_SUBSCRIPTION_ID }}"
+ export GPT_MIN_CAPACITY=${{ env.GPT_MIN_CAPACITY }}
+ export TEXT_EMBEDDING_MIN_CAPACITY=${{ env.TEXT_EMBEDDING_MIN_CAPACITY }}
+ export AZURE_REGIONS="${{ vars.AZURE_REGIONS }}"
+
+ chmod +x scripts/checkquota.sh
+ if ! scripts/checkquota.sh; then
+ # If quota check fails due to insufficient quota, set the flag
+ if grep -q "No region with sufficient quota found" scripts/checkquota.sh; then
+ echo "QUOTA_FAILED=true" >> $GITHUB_ENV
+ fi
+ exit 1 # Fail the pipeline if any other failure occurs
+ fi
+
+
+ - name: Send Notification on Quota Failure
+ if: env.QUOTA_FAILED == 'true'
+ run: |
+ RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
+ EMAIL_BODY=$(cat <Dear Team,
The quota check has failed, and the pipeline cannot proceed.
Build URL: ${RUN_URL}
Please take necessary action.
Best regards,
Your Automation Team
"
+ }
+ EOF
+ )
+
+ curl -X POST "${{ secrets.LOGIC_APP_URL }}" \
+ -H "Content-Type: application/json" \
+ -d "$EMAIL_BODY" || echo "Failed to send notification"
+
+ - name: Fail Pipeline if Quota Check Fails
+ if: env.QUOTA_FAILED == 'true'
+ run: exit 1
+
+ - name: Set Deployment Region
+ id: set_region
+ run: |
+ echo "Selected Region: $VALID_REGION"
+ echo "AZURE_AI_LOCATION=$VALID_REGION" >> $GITHUB_ENV
+ echo "AZURE_LOCATION=$VALID_REGION" >> $GITHUB_ENV
+ echo "AZURE_LOCATION=$VALID_REGION" >> $GITHUB_OUTPUT
+ if [ "$VALID_REGION" == "eastus" ] || [ "$VALID_REGION" == "westus3" ]; then
+ echo "AZURE_LOCATION=uksouth" >> $GITHUB_ENV
+ echo "AZURE_LOCATION=uksouth" >> $GITHUB_OUTPUT
+ fi
+
+ - name: Generate Resource Group Name
+ id: generate_rg_name
+ run: |
+ echo "Generating a unique resource group name..."
+ ACCL_NAME="docgen" # Account name as specified
+ SHORT_UUID=$(uuidgen | cut -d'-' -f1)
+ UNIQUE_RG_NAME="arg-${ACCL_NAME}-${SHORT_UUID}"
+ echo "RESOURCE_GROUP_NAME=${UNIQUE_RG_NAME}" >> $GITHUB_ENV
+ echo "Generated RESOURCE_GROUP_NAME: ${UNIQUE_RG_NAME}"
+
+ - name: Setup Azure Developer CLI
+ run: |
+ curl -fsSL https://aka.ms/install-azd.sh | sudo bash
+ azd version
+
+ - name: Login to Azure
+ id: login-azure
+ run: |
+ az login --service-principal -u ${{ secrets.AZURE_CLIENT_ID }} -p ${{ secrets.AZURE_CLIENT_SECRET }} --tenant ${{ secrets.AZURE_TENANT_ID }}
+ azd auth login --client-id ${{ secrets.AZURE_CLIENT_ID }} --client-secret ${{ secrets.AZURE_CLIENT_SECRET }} --tenant-id ${{ secrets.AZURE_TENANT_ID }}
+
+ - name: Install Bicep CLI
+ run: az bicep install
+
+ - name: Check and Create Resource Group
+ id: check_create_rg
+ run: |
+ set -e
+ echo "Checking if resource group exists..."
+ rg_exists=$(az group exists --name $RESOURCE_GROUP_NAME)
+ if [ "$rg_exists" = "false" ]; then
+ echo "Resource group does not exist. Creating..."
+ az group create --name $RESOURCE_GROUP_NAME --location $AZURE_LOCATION || { echo "Error creating resource group"; exit 1; }
+ else
+ echo "Resource group already exists."
+ fi
+ echo "RESOURCE_GROUP_NAME=$RESOURCE_GROUP_NAME" >> $GITHUB_OUTPUT
+
+ - name: Generate Unique Solution Prefix
+ id: generate_solution_prefix
+ run: |
+ set -e
+ COMMON_PART="psldg"
+ TIMESTAMP=$(date +%s)
+ UPDATED_TIMESTAMP=$(echo $TIMESTAMP | tail -c 6)
+ UNIQUE_SOLUTION_PREFIX="${COMMON_PART}${UPDATED_TIMESTAMP}"
+ echo "SOLUTION_PREFIX=${UNIQUE_SOLUTION_PREFIX}" >> $GITHUB_ENV
+ echo "Generated SOLUTION_PREFIX: ${UNIQUE_SOLUTION_PREFIX}"
+
+ - name: Generate Unique Docker Image Tag
+ id: generate_docker_tag
+ run: |
+ if [[ "${{ env.BUILD_DOCKER_IMAGE }}" == "true" ]]; then
+ echo "đ¨ Building new Docker image - generating unique tag..."
+ # Generate unique tag for manual deployment runs
+ TIMESTAMP=$(date +%Y%m%d-%H%M%S)
+ RUN_ID="${{ github.run_id }}"
+ BRANCH_NAME="${{ env.BRANCH_NAME }}"
+ # Sanitize branch name for Docker tag (replace invalid characters with hyphens)
+ CLEAN_BRANCH_NAME=$(echo "$BRANCH_NAME" | sed 's/[^a-zA-Z0-9._-]/-/g' | sed 's/--*/-/g' | sed 's/^-\|-$//g')
+ UNIQUE_TAG="${CLEAN_BRANCH_NAME}-${TIMESTAMP}-${RUN_ID}"
+ echo "IMAGE_TAG=$UNIQUE_TAG" >> $GITHUB_ENV
+ echo "IMAGE_TAG=$UNIQUE_TAG" >> $GITHUB_OUTPUT
+ echo "Generated unique Docker tag: $UNIQUE_TAG"
+ else
+ echo "đˇī¸ Using existing Docker image based on branch..."
+ BRANCH_NAME="${{ env.BRANCH_NAME }}"
+ echo "Current branch: $BRANCH_NAME"
+
+ # Determine image tag based on branch
+ if [[ "$BRANCH_NAME" == "main" ]]; then
+ IMAGE_TAG="latest_waf"
+ echo "Using main branch - image tag: latest_waf"
+ elif [[ "$BRANCH_NAME" == "dev" ]]; then
+ IMAGE_TAG="dev"
+ echo "Using dev branch - image tag: dev"
+ elif [[ "$BRANCH_NAME" == "demo" ]]; then
+ IMAGE_TAG="demo"
+ echo "Using demo branch - image tag: demo"
+ else
+ IMAGE_TAG="latest_waf"
+ echo "Using default for branch '$BRANCH_NAME' - image tag: latest_waf"
+ fi
+
+ echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV
+ echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_OUTPUT
+ echo "Using existing Docker image tag: $IMAGE_TAG"
+ fi
+
+ - name: Set up Docker Buildx
+ if: env.BUILD_DOCKER_IMAGE == true
+ uses: docker/setup-buildx-action@v3
+
+ - name: Log in to Azure Container Registry
+ if: env.BUILD_DOCKER_IMAGE == true
+ uses: azure/docker-login@v2
+ with:
+ login-server: ${{ secrets.ACR_DEV_LOGIN_SERVER }}
+ username: ${{ secrets.ACR_DEV_USERNAME }}
+ password: ${{ secrets.ACR_DEV_PASSWORD }}
+
+ - name: Build and Push Docker Image
+ if: env.BUILD_DOCKER_IMAGE == true
+ id: build_push_image
+ uses: docker/build-push-action@v6
+ with:
+ context: ./src
+ file: ./src/WebApp.Dockerfile
+ push: true
+ tags: |
+ ${{ secrets.ACR_DEV_LOGIN_SERVER }}/webapp:${{ steps.generate_docker_tag.outputs.IMAGE_TAG }}
+ ${{ secrets.ACR_DEV_LOGIN_SERVER }}/webapp:${{ steps.generate_docker_tag.outputs.IMAGE_TAG }}_${{ github.run_number }}
+
+ - name: Verify Docker Image Build
+ if: env.BUILD_DOCKER_IMAGE == true
+ run: |
+ echo "â
Docker image successfully built and pushed"
+ echo "Image tag: ${{ env.IMAGE_TAG }}"
+ echo "Run number: ${{ github.run_number }}"
+
+ - name: Verify Docker Image Selection
+ if: env.BUILD_DOCKER_IMAGE == false
+ run: |
+ echo "â
Using existing Docker image: latest_waf"
+ echo "Image tag: ${{ env.IMAGE_TAG }}"
+
+ - name: Generate Unique Environment Name
+ id: generate_env_name
+ run: |
+ COMMON_PART="pslc"
+ TIMESTAMP=$(date +%s)
+ UPDATED_TIMESTAMP=$(echo $TIMESTAMP | tail -c 6)
+ UNIQUE_ENV_NAME="${COMMON_PART}${UPDATED_TIMESTAMP}"
+ echo "ENV_NAME=${UNIQUE_ENV_NAME}" >> $GITHUB_ENV
+ echo "Generated Environment Name: ${UNIQUE_ENV_NAME}"
+ echo "ENV_NAME=${UNIQUE_ENV_NAME}" >> $GITHUB_OUTPUT
+
+ - name: Configure Parameters Based on WAF Setting
+ run: |
+ if [[ "${{ env.WAF_ENABLED }}" == "true" ]]; then
+ echo "đ§ Configuring WAF deployment - copying main.waf.parameters.json to main.parameters.json..."
+ cp infra/main.waf.parameters.json infra/main.parameters.json
+ echo "â
Successfully copied WAF parameters to main parameters file"
+ else
+ echo "đ§ Configuring Non-WAF deployment - using default main.parameters.json..."
+ # Ensure we have the original parameters file if it was overwritten
+ if [[ -f infra/main.waf.parameters.json ]] && [[ ! -f infra/main.parameters.json.backup ]]; then
+ echo "Backing up original parameters file..."
+ git checkout HEAD -- infra/main.parameters.json || echo "Using existing main.parameters.json"
+ fi
+ fi
+
+ - name: Display Docker Image Tag
+ run: |
+ echo "=== Docker Image Information ==="
+ echo "Docker Image Tag: ${{ env.IMAGE_TAG }}"
+ echo "Registry: ${{ secrets.ACR_DEV_LOGIN_SERVER }}"
+ echo "Full Image: ${{ secrets.ACR_DEV_LOGIN_SERVER }}/webapp:${{ env.IMAGE_TAG }}"
+ echo "================================"
+
+ - name: Deploy using azd up and extract values (${{ env.WAF_ENABLED == 'true' && 'WAF' || 'Non-WAF' }}+${{ env.EXP == 'true' && 'EXP' || 'Non-EXP' }})
+ id: get_output
+ run: |
+ set -e
+ echo "Starting azd deployment..."
+ echo "WAF Enabled: ${{ env.WAF_ENABLED }}"
+ echo "EXP: ${{ env.EXP }}"
+ echo "Using Docker Image Tag: ${{ env.IMAGE_TAG }}"
+
+ # Install azd (Azure Developer CLI)
+ curl -fsSL https://aka.ms/install-azd.sh | bash
+
+ # Generate current timestamp in desired format: YYYY-MM-DDTHH:MM:SS.SSSSSSSZ
+ current_date=$(date -u +"%Y-%m-%dT%H:%M:%S.%7NZ")
+
+ echo "Creating environment..."
+ azd env new $ENV_NAME --no-prompt
+ echo "Environment created: $ENV_NAME"
+
+ echo "Setting default subscription..."
+ azd config set defaults.subscription ${{ secrets.AZURE_SUBSCRIPTION_ID }}
+
+ # Set additional parameters
+ azd env set AZURE_SUBSCRIPTION_ID="${{ secrets.AZURE_SUBSCRIPTION_ID }}"
+ azd env set AZURE_ENV_OPENAI_LOCATION="$AZURE_LOCATION"
+ azd env set AZURE_RESOURCE_GROUP="$RESOURCE_GROUP_NAME"
+ azd env set AZURE_ENV_IMAGETAG="${{ env.IMAGE_TAG }}"
+ azd env set AZURE_DEV_COLLECT_TELEMETRY="no"
+
+ # Set ACR name only when building Docker image
+ if [[ "${{ env.BUILD_DOCKER_IMAGE }}" == "true" ]]; then
+ # Extract ACR name from login server and set as environment variable
+ ACR_NAME=$(echo "${{ secrets.ACR_DEV_LOGIN_SERVER }}" | cut -d'.' -f1)
+ azd env set AZURE_ENV_ACR_NAME="$ACR_NAME"
+ echo "Set ACR name to: $ACR_NAME"
+ else
+ echo "Skipping ACR name configuration (using existing image)"
+ fi
+
+ if [[ "${{ env.EXP }}" == "true" ]]; then
+ echo "â
EXP ENABLED - Setting EXP parameters..."
+
+ # Set EXP variables dynamically
+ if [[ -n "${{ github.event.inputs.AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID }}" ]]; then
+ EXP_LOG_ANALYTICS_ID="${{ github.event.inputs.AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID }}"
+ else
+ EXP_LOG_ANALYTICS_ID="${{ secrets.EXP_LOG_ANALYTICS_WORKSPACE_ID }}"
+ fi
+
+ if [[ -n "${{ github.event.inputs.AZURE_EXISTING_AI_PROJECT_RESOURCE_ID }}" ]]; then
+ EXP_AI_PROJECT_ID="${{ github.event.inputs.AZURE_EXISTING_AI_PROJECT_RESOURCE_ID }}"
+ else
+ EXP_AI_PROJECT_ID="${{ secrets.EXP_AI_PROJECT_RESOURCE_ID }}"
+ fi
+
+ echo "AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID: $EXP_LOG_ANALYTICS_ID"
+ echo "AZURE_EXISTING_AI_PROJECT_RESOURCE_ID: $EXP_AI_PROJECT_ID"
+ azd env set AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID="$EXP_LOG_ANALYTICS_ID"
+ azd env set AZURE_EXISTING_AI_PROJECT_RESOURCE_ID="$EXP_AI_PROJECT_ID"
+ else
+ echo "â EXP DISABLED - Skipping EXP parameters"
+ if [[ -n "${{ github.event.inputs.AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID }}" ]] || [[ -n "${{ github.event.inputs.AZURE_EXISTING_AI_PROJECT_RESOURCE_ID }}" ]]; then
+ echo "â ī¸ Warning: EXP parameter values provided but EXP is disabled. These values will be ignored."
+ fi
+ fi
+
+ # Deploy using azd up
+ azd up --no-prompt
+
+ # Get deployment outputs using azd
+ echo "Extracting deployment outputs..."
+ DEPLOY_OUTPUT=$(azd env get-values --output json)
+ echo "Deployment output: $DEPLOY_OUTPUT"
+
+ if [[ -z "$DEPLOY_OUTPUT" ]]; then
+ echo "Error: Deployment output is empty. Please check the deployment logs."
+ exit 1
+ fi
+
+ # Extract values from azd output (adjust these based on actual output variable names)
+ export AI_FOUNDRY_RESOURCE_ID=$(echo "$DEPLOY_OUTPUT" | jq -r '.AI_FOUNDRY_RESOURCE_ID // empty')
+ echo "AI_FOUNDRY_RESOURCE_ID=$AI_FOUNDRY_RESOURCE_ID" >> $GITHUB_ENV
+ export AI_SEARCH_SERVICE_NAME=$(echo "$DEPLOY_OUTPUT" | jq -r '.AI_SEARCH_SERVICE_NAME // empty')
+ echo "AI_SEARCH_SERVICE_NAME=$AI_SEARCH_SERVICE_NAME" >> $GITHUB_ENV
+ export COSMOS_DB_ACCOUNT_NAME=$(echo "$DEPLOY_OUTPUT" | jq -r '.COSMOS_DB_ACCOUNT_NAME // empty')
+ echo "COSMOS_DB_ACCOUNT_NAME=$COSMOS_DB_ACCOUNT_NAME" >> $GITHUB_ENV
+ export STORAGE_ACCOUNT_NAME=$(echo "$DEPLOY_OUTPUT" | jq -r '.STORAGE_ACCOUNT_NAME // empty')
+ echo "STORAGE_ACCOUNT_NAME=$STORAGE_ACCOUNT_NAME" >> $GITHUB_ENV
+ export STORAGE_CONTAINER_NAME=$(echo "$DEPLOY_OUTPUT" | jq -r '.STORAGE_CONTAINER_NAME // empty')
+ echo "STORAGE_CONTAINER_NAME=$STORAGE_CONTAINER_NAME" >> $GITHUB_ENV
+ export KEY_VAULT_NAME=$(echo "$DEPLOY_OUTPUT" | jq -r '.KEY_VAULT_NAME // empty')
+ echo "KEY_VAULT_NAME=$KEY_VAULT_NAME" >> $GITHUB_ENV
+ export SQL_SERVER_NAME=$(echo "$DEPLOY_OUTPUT" | jq -r '.SQLDB_SERVER_NAME // empty')
+ echo "SQL_SERVER_NAME=$SQL_SERVER_NAME" >> $GITHUB_ENV
+ export SQL_DATABASE=$(echo "$DEPLOY_OUTPUT" | jq -r '.SQLDB_DATABASE // empty')
+ echo "SQL_DATABASE=$SQL_DATABASE" >> $GITHUB_ENV
+ export CLIENT_ID=$(echo "$DEPLOY_OUTPUT" | jq -r '.MANAGEDIDENTITY_SQL_CLIENTID // empty')
+ echo "CLIENT_ID=$CLIENT_ID" >> $GITHUB_ENV
+ export CLIENT_NAME=$(echo "$DEPLOY_OUTPUT" | jq -r '.MANAGEDIDENTITY_SQL_NAME // empty')
+ echo "CLIENT_NAME=$CLIENT_NAME" >> $GITHUB_ENV
+ export MANAGEDIDENTITY_WEBAPP_CLIENTID=$(echo "$DEPLOY_OUTPUT" | jq -r '.MANAGEDIDENTITY_WEBAPP_CLIENTID // empty')
+ echo "MANAGEDIDENTITY_WEBAPP_CLIENTID=$MANAGEDIDENTITY_WEBAPP_CLIENTID" >> $GITHUB_ENV
+ export RESOURCE_GROUP_NAME=$(echo "$DEPLOY_OUTPUT" | jq -r '.RESOURCE_GROUP_NAME // .AZURE_RESOURCE_GROUP // empty')
+ [[ -z "$RESOURCE_GROUP_NAME" ]] && export RESOURCE_GROUP_NAME="$RESOURCE_GROUP_NAME"
+ echo "RESOURCE_GROUP_NAME=$RESOURCE_GROUP_NAME" >> $GITHUB_ENV
+ WEBAPP_URL=$(echo "$DEPLOY_OUTPUT" | jq -r '.WEB_APP_URL // .SERVICE_BACKEND_ENDPOINT_URL // empty')
+ echo "WEBAPP_URL=$WEBAPP_URL" >> $GITHUB_OUTPUT
+ WEB_APP_NAME=$(echo "$DEPLOY_OUTPUT" | jq -r '.WEB_APP_NAME // .SERVICE_BACKEND_NAME // empty')
+ echo "WEB_APP_NAME=$WEB_APP_NAME" >> $GITHUB_ENV
+
+ # echo "đ§ Disabling AUTH_ENABLED for the web app..."
+ # if [[ -n "$WEB_APP_NAME" && -n "$RESOURCE_GROUP_NAME" ]]; then
+ # az webapp config appsettings set -g "$RESOURCE_GROUP_NAME" -n "$WEB_APP_NAME" --settings AUTH_ENABLED=false
+ # else
+ # echo "Warning: Could not disable AUTH_ENABLED - WEB_APP_NAME or RESOURCE_GROUP_NAME not found"
+ # fi
+
+ sleep 30
+
+ - name: Run Post-Deployment Script
+ id: post_deploy
+ env:
+ AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
+ run: |
+ set -e
+ az account set --subscription "${{ secrets.AZURE_SUBSCRIPTION_ID }}"
+
+ echo "Running post-deployment script..."
+
+ bash ./infra/scripts/process_sample_data.sh \
+ "$STORAGE_ACCOUNT_NAME" \
+ "$STORAGE_CONTAINER_NAME" \
+ "$KEY_VAULT_NAME" \
+ "$COSMOS_DB_ACCOUNT_NAME" \
+ "$RESOURCE_GROUP_NAME" \
+ "$AI_SEARCH_SERVICE_NAME" \
+ "${{ secrets.AZURE_CLIENT_ID }}" \
+ "$AI_FOUNDRY_RESOURCE_ID"
+
+ - name: Logout from Azure
+ if: always()
+ run: |
+ az logout
+ echo "Logged out from Azure."
+
+ e2e-test:
+ # Run e2e tests for automatic triggers, when manually enabled, or when existing webapp URL is provided
+ if: always() && (github.event_name != 'workflow_dispatch' || github.event.inputs.run_e2e_tests == true || github.event.inputs.run_e2e_tests == null || github.event.inputs.existing_webapp_url != '')
+ needs: [deploy]
+ uses: ./.github/workflows/test-automation.yml
+ with:
+ DOCGEN_URL: ${{ github.event.inputs.existing_webapp_url || needs.deploy.outputs.WEBAPP_URL }}
+ secrets: inherit
+
+ cleanup-deployment:
+ # Cleanup for automatic triggers or when manually enabled (skip cleanup when using existing webapp URL)
+ if: always() && needs.deploy.result != 'skipped' && needs.deploy.outputs.RESOURCE_GROUP_NAME != '' && (github.event_name != 'workflow_dispatch' || (github.event.inputs.cleanup_resources == true && github.event.inputs.existing_webapp_url == ''))
+ needs: [deploy]
+ runs-on: ubuntu-latest
+ env:
+ RESOURCE_GROUP_NAME: ${{ needs.deploy.outputs.RESOURCE_GROUP_NAME }}
+ AZURE_LOCATION: ${{ needs.deploy.outputs.AZURE_LOCATION }}
+ ENV_NAME: ${{ needs.deploy.outputs.ENV_NAME }}
+ IMAGE_TAG: ${{ needs.deploy.outputs.IMAGE_TAG }}
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v4
+
+ - name: Setup Azure Developer CLI
+ run: |
+ curl -fsSL https://aka.ms/install-azd.sh | sudo bash
+ azd version
+
+ - name: Login to Azure
+ run: |
+ azd auth login --client-id ${{ secrets.AZURE_CLIENT_ID }} --client-secret ${{ secrets.AZURE_CLIENT_SECRET }} --tenant-id ${{ secrets.AZURE_TENANT_ID }}
+ azd config set defaults.subscription ${{ secrets.AZURE_SUBSCRIPTION_ID }}
+
+ - name: Setup Azure CLI for Docker cleanup
+ run: |
+ curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
+ az --version
+
+ - name: Login to Azure CLI for Docker cleanup
+ run: |
+ az login --service-principal -u ${{ secrets.AZURE_CLIENT_ID }} -p ${{ secrets.AZURE_CLIENT_SECRET }} --tenant ${{ secrets.AZURE_TENANT_ID }}
+
+ - name: Delete Docker Images from ACR
+ run: |
+ set -e
+ echo "đī¸ Cleaning up Docker images from Azure Container Registry..."
+
+ if [[ -n "${{ env.IMAGE_TAG }}" && "${{ env.IMAGE_TAG }}" != "latest_waf" ]]; then
+ echo "Deleting Docker images with tag: ${{ env.IMAGE_TAG }}"
+
+ # Delete the main image
+ echo "Deleting image: ${{ secrets.ACR_DEV_LOGIN_SERVER }}/webapp:${{ env.IMAGE_TAG }}"
+ az acr repository delete --name $(echo "${{ secrets.ACR_DEV_LOGIN_SERVER }}" | cut -d'.' -f1) \
+ --image webapp:${{ env.IMAGE_TAG }} --yes || echo "Warning: Failed to delete main image or image not found"
+
+ # Delete the image with run number suffix
+ echo "Deleting image: ${{ secrets.ACR_DEV_LOGIN_SERVER }}/webapp:${{ env.IMAGE_TAG }}_${{ github.run_number }}"
+ az acr repository delete --name $(echo "${{ secrets.ACR_DEV_LOGIN_SERVER }}" | cut -d'.' -f1) \
+ --image webapp:${{ env.IMAGE_TAG }}_${{ github.run_number }} --yes || echo "Warning: Failed to delete run-numbered image or image not found"
+
+ echo "â
Docker images cleanup completed"
+ else
+ echo "â ī¸ Skipping Docker image cleanup (using latest_waf or no custom image tag)"
+ fi
+
+ - name: Select Environment
+ run: |
+ # Try to select the environment if it exists, otherwise create a minimal environment for cleanup
+ azd env list
+ if azd env list | grep -q "${{ env.ENV_NAME }}"; then
+ echo "Environment ${{ env.ENV_NAME }} found, selecting it..."
+ azd env select ${{ env.ENV_NAME }}
+ else
+ echo "Environment ${{ env.ENV_NAME }} not found, creating minimal environment for cleanup..."
+ azd env new ${{ env.ENV_NAME }} --no-prompt
+ azd env set AZURE_RESOURCE_GROUP "${{ env.RESOURCE_GROUP_NAME }}"
+ azd env set AZURE_SUBSCRIPTION_ID "${{ secrets.AZURE_SUBSCRIPTION_ID }}"
+ azd env set AZURE_ENV_OPENAI_LOCATION="${{ env.AZURE_LOCATION }}"
+ azd env set AZURE_LOCATION="${{ env.AZURE_LOCATION }}"
+ fi
+
+ - name: Delete deployment using azd
+ run: |
+ set -e
+ echo "Deleting deployment..."
+ azd down --purge --force --no-prompt
+ echo "Deployment deleted successfully."
+
+ - name: Send Notification on Failure
+ if: always() && (failure() || needs.deploy.result == 'failure')
+ run: |
+ RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
+
+ # Get deployment configuration for notification
+ WAF_STATUS="${{ github.event.inputs.waf_enabled || true }}"
+ EXP_STATUS="${{ env.EXP || false }}"
+ CLEANUP_STATUS="${{ github.event.inputs.cleanup_resources || true }}"
+
+ # Construct the email body
+ EMAIL_BODY=$(cat <Dear Team,We would like to inform you that the document-generation-solution-accelerator Unified Deployment process has encountered an issue and has failed to complete successfully.
Configuration:
- WAF Enabled: ${WAF_STATUS}
- EXP: ${EXP_STATUS}
- Cleanup: ${CLEANUP_STATUS}
Build URL: ${RUN_URL}
Please investigate the matter at your earliest convenience.
Best regards,
Your Automation Team
"
+ }
+ EOF
+ )
+
+ # Send the notification
+ curl -X POST "${{ secrets.LOGIC_APP_URL }}" \
+ -H "Content-Type: application/json" \
+ -d "$EMAIL_BODY" || echo "Failed to send notification"
+
+ - name: Logout from Azure
+ if: always()
+ run: |
+ azd auth logout
+ az logout || echo "Warning: Failed to logout from Azure CLI"
+ echo "Logged out from Azure."
diff --git a/docker-workflow-test.md b/docker-workflow-test.md
new file mode 100644
index 000000000..5ef531955
--- /dev/null
+++ b/docker-workflow-test.md
@@ -0,0 +1,9 @@
+# Docker Workflow Test
+
+This file is created to trigger the "Build Docker and Optional Push" workflow, which should then trigger the "Deploy-Test-Cleanup (Parameterized)" workflow via workflow_run.
+
+**Chain of events expected:**
+1. Push this file â triggers "Build Docker and Optional Push"
+2. "Build Docker and Optional Push" completes â triggers "Deploy-Test-Cleanup (Parameterized)"
+
+Test timestamp: October 23, 2025
\ No newline at end of file
diff --git a/infra/main.bicep b/infra/main.bicep
index 56e68a3ae..52c304da3 100644
--- a/infra/main.bicep
+++ b/infra/main.bicep
@@ -623,7 +623,7 @@ module aiSearch 'br/public:avm/res/search/search-service:0.11.1' = {
diagnosticSettings: enableMonitoring ? [{ workspaceResourceId: logAnalyticsWorkspaceResourceId }] : null
disableLocalAuth: false
hostingMode: 'default'
- sku: enableScalability ? 'standard' : 'basic'
+ sku: enableScalability ? 'standard' : 'standard'
managedIdentities: { systemAssigned: true }
networkRuleSet: {
bypass: 'AzureServices'
diff --git a/infra/main.parameters.json b/infra/main.parameters.json
index b84739b81..c8b86c4cc 100644
--- a/infra/main.parameters.json
+++ b/infra/main.parameters.json
@@ -40,6 +40,9 @@
},
"azureExistingAIProjectResourceId":{
"value": "${AZURE_EXISTING_AI_PROJECT_RESOURCE_ID}"
+ },
+ "acrName": {
+ "value": "${AZURE_ENV_ACR_NAME}"
}
}
}
diff --git a/infra/main.waf.parameters.json b/infra/main.waf.parameters.json
index ab91c89cf..b65a3ccb7 100644
--- a/infra/main.waf.parameters.json
+++ b/infra/main.waf.parameters.json
@@ -58,6 +58,9 @@
},
"azureExistingAIProjectResourceId":{
"value": "${AZURE_EXISTING_AI_PROJECT_RESOURCE_ID}"
+ },
+ "acrName": {
+ "value": "${AZURE_ENV_ACR_NAME}"
}
}
}
diff --git a/pr-test-trigger.md b/pr-test-trigger.md
new file mode 100644
index 000000000..215cd82b4
--- /dev/null
+++ b/pr-test-trigger.md
@@ -0,0 +1,17 @@
+# PR Workflow Test
+
+This is a test file created to trigger the pull request workflow.
+
+**Test Details:**
+- Date: October 23, 2025
+- Purpose: Testing the pull request trigger in deploy-Parameterized.yml workflow
+- Expected outcome: Workflow should run with PR-specific configuration (WAF_ENABLED=false, EXP=false, etc.)
+
+## What the workflow should do:
+1. Trigger on PR to main branch
+2. Set automatic configuration for PR triggers
+3. Deploy resources to Azure
+4. Run E2E tests
+5. Clean up resources after testing
+
+This file can be safely deleted after testing is complete.
\ No newline at end of file