Added Deployment pipeline #1
  
    
      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-Test-Cleanup (Non-Waf) | |
| on: | |
| push: | |
| branches: | |
| - deploy-azd-waf | |
| workflow_run: | |
| workflows: ["Build Docker and Optional Push - Client Advisor"] | |
| types: | |
| - completed | |
| branches: | |
| - main | |
| - hotfix | |
| - dev | |
| - demo | |
| - deploy-azd-waf | |
| workflow_dispatch: | |
| inputs: | |
| cleanup_resources: | |
| description: 'cleanup deployed resources' | |
| required: false | |
| default: 'true' | |
| type: choice | |
| options: | |
| - 'true' | |
| - 'false' | |
| schedule: | |
| - cron: "0 6,18 * * *" # Runs at 6:00 AM and 6:00 PM GMT | |
| env: | |
| GPT_MIN_CAPACITY: 200 | |
| TEXT_EMBEDDING_MIN_CAPACITY: 80 | |
| BRANCH_NAME: ${{ github.event.workflow_run.head_branch || github.head_ref || github.ref_name }} | |
| jobs: | |
| deploy: | |
| runs-on: ubuntu-22.04 | |
| outputs: | |
| RESOURCE_GROUP_NAME: ${{ steps.generate_env_name.outputs.RESOURCE_GROUP_NAME }} | |
| WEBAPP_URL: ${{ steps.get_output.outputs.WEBAPP_URL }} | |
| DEPLOYMENT_SUCCESS: ${{ steps.deployment_status.outputs.SUCCESS }} | |
| AI_SERVICES_NAME: ${{ steps.get_ai_services_name.outputs.AI_SERVICES_NAME }} | |
| KEYVAULTS: ${{ steps.list_keyvaults.outputs.KEYVAULTS }} | |
| AZURE_LOCATION: ${{ steps.set_region.outputs.AZURE_LOCATION }} | |
| SOLUTION_PREFIX: ${{ steps.generate_solution_prefix.outputs.SOLUTION_PREFIX }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install ODBC Driver 18 for SQL Server | |
| run: | | |
| curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add - | |
| sudo add-apt-repository "$(curl https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/prod.list)" | |
| sudo apt-get update | |
| sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18 | |
| sudo apt-get install -y unixodbc-dev | |
| - name: Setup Azure CLI | |
| run: curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash | |
| - name: Login to Azure | |
| run: | | |
| az login --service-principal -u ${{ secrets.AZURE_CLIENT_ID }} -p ${{ secrets.AZURE_CLIENT_SECRET }} --tenant ${{ secrets.AZURE_TENANT_ID }} | |
| az account set --subscription ${{ secrets.AZURE_SUBSCRIPTION_ID }} | |
| - 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_CA }}" | |
| chmod +x infra/scripts/checkquota.sh | |
| if ! infra/scripts/checkquota.sh; then | |
| if grep -q "No region with sufficient quota found" infra/scripts/checkquota_ca.sh; then | |
| echo "QUOTA_FAILED=true" >> $GITHUB_ENV | |
| fi | |
| exit 1 | |
| fi | |
| - name: Notify on Quota Failure | |
| if: env.QUOTA_FAILED == 'true' | |
| run: | | |
| RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" | |
| curl -X POST "${{ secrets.LOGIC_APP_URL }}" \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "subject": "CA Deployment - Quota Check Failed", | |
| "body": "<p>Dear Team,</p><p>We would like to inform you that the Build-your-own-copilot-Solution-Accelerator(Client Advisor) Deployment Automation process has encountered a quota issue. Hence, unable to proceed with the deployment.</p><p><a href=\"'${RUN_URL}'\">View run</a></p>" | |
| }' | |
| - name: Fail on Quota Check | |
| if: env.QUOTA_FAILED == 'true' | |
| run: exit 1 | |
| - name: Install Bicep CLI | |
| run: az bicep install | |
| - name: Set Deployment Region | |
| id: set_region | |
| run: | | |
| echo "Selected Region: $VALID_REGION" | |
| echo "AZURE_LOCATION=$VALID_REGION" >> $GITHUB_ENV | |
| echo "AZURE_LOCATION=$VALID_REGION" >> $GITHUB_OUTPUT | |
| - name: Generate Environment Name for azd | |
| id: generate_env_name | |
| run: | | |
| echo "Generating a unique environment name for azd..." | |
| ACCL_NAME="ca" # Account name as specified | |
| SHORT_UUID=$(uuidgen | cut -d'-' -f1) | |
| UNIQUE_ENV_NAME="${ACCL_NAME}-${SHORT_UUID}" | |
| echo "AZURE_ENV_NAME=${UNIQUE_ENV_NAME}" >> $GITHUB_ENV | |
| echo "Generated AZURE_ENV_NAME: ${UNIQUE_ENV_NAME}" | |
| # Generate resource group name following azd convention | |
| UNIQUE_RG_NAME="rg-${UNIQUE_ENV_NAME}" | |
| echo "RESOURCE_GROUP_NAME=${UNIQUE_RG_NAME}" >> $GITHUB_ENV | |
| echo "RESOURCE_GROUP_NAME=${UNIQUE_RG_NAME}" >> $GITHUB_OUTPUT | |
| echo "Generated RESOURCE_GROUP_NAME: ${UNIQUE_RG_NAME}" | |
| - name: Generate Unique Solution Prefix | |
| id: generate_solution_prefix | |
| run: | | |
| set -e | |
| COMMON_PART="pslc" | |
| TIMESTAMP=$(date +%s) | |
| UPDATED_TIMESTAMP=$(echo $TIMESTAMP | tail -c 3) | |
| UNIQUE_SOLUTION_PREFIX="${COMMON_PART}${UPDATED_TIMESTAMP}" | |
| echo "SOLUTION_PREFIX=${UNIQUE_SOLUTION_PREFIX}" >> $GITHUB_ENV | |
| echo "SOLUTION_PREFIX=${UNIQUE_SOLUTION_PREFIX}" >> $GITHUB_OUTPUT | |
| echo "Generated SOLUTION_PREFIX: ${UNIQUE_SOLUTION_PREFIX}" | |
| - name: Determine Tag | |
| id: determine_tag | |
| run: | | |
| BRANCH=${{ github.ref_name }} | |
| if [[ "$BRANCH" == "main" ]]; then TAG="latest_waf" | |
| elif [[ "$BRANCH" == "dev" ]]; then TAG="dev" | |
| elif [[ "$BRANCH" == "demo" ]]; then TAG="demo" | |
| else TAG="latest_waf"; fi | |
| echo "IMAGE_TAG=$TAG" >> $GITHUB_ENV | |
| echo "Image Tag: $TAG" | |
| - name: Deploy using azd up and extract values | |
| id: get_output | |
| run: | | |
| set -e | |
| echo "Starting azd deployment..." | |
| # 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") | |
| # Set azd environment variables | |
| export AZURE_SUBSCRIPTION_ID="${{ secrets.AZURE_SUBSCRIPTION_ID }}" | |
| export AZURE_ENV_COSMOS_LOCATION="westus" | |
| export AZURE_ENV_MODEL_DEPLOYMENT_TYPE="Standard" | |
| export AZURE_ENV_MODEL_NAME="gpt-4o" | |
| export AZURE_ENV_MODEL_VERSION="2024-08-06" | |
| export AZURE_ENV_MODEL_CAPACITY="${{ env.GPT_MIN_CAPACITY }}" | |
| export AZURE_ENV_EMBEDDING_MODEL_NAME="text-embedding-3-large" | |
| export AZURE_ENV_EMBEDDING_MODEL_CAPACITY="${{ env.TEXT_EMBEDDING_MIN_CAPACITY }}" | |
| export AZURE_ENV_IMAGETAG="${{ env.IMAGE_TAG }}" | |
| export AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID="" | |
| export AZURE_EXISTING_AI_PROJECT_RESOURCE_ID="" | |
| # Initialize azd environment | |
| azd env new ${{ env.AZURE_ENV_NAME }} --location ${{ env.AZURE_LOCATION }} | |
| # Set additional parameters for tags | |
| azd env set AZURE_ENV_CREATED_BY "Pipeline" | |
| azd env set AZURE_ENV_SECURITY_CONTROL "Ignore" | |
| azd env set AZURE_ENV_PURPOSE "Deploying and Cleaning Up Resources for Validation" | |
| azd env set AZURE_ENV_CREATED_DATE "$current_date" | |
| # 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 SEARCH_SERVICE_NAME=$(echo "$DEPLOY_OUTPUT" | jq -r '.AI_SEARCH_SERVICE_NAME // empty') | |
| echo "SEARCH_SERVICE_NAME=$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=$(echo "$DEPLOY_OUTPUT" | jq -r '.STORAGE_ACCOUNT_NAME // empty') | |
| echo "STORAGE_ACCOUNT=$STORAGE_ACCOUNT" >> $GITHUB_ENV | |
| export STORAGE_CONTAINER=$(echo "$DEPLOY_OUTPUT" | jq -r '.STORAGE_CONTAINER_NAME // empty') | |
| echo "STORAGE_CONTAINER=$STORAGE_CONTAINER" >> $GITHUB_ENV | |
| export KEYVAULT_NAME=$(echo "$DEPLOY_OUTPUT" | jq -r '.KEY_VAULT_NAME // empty') | |
| echo "KEYVAULT_NAME=$KEYVAULT_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 RG_NAME=$(echo "$DEPLOY_OUTPUT" | jq -r '.RESOURCE_GROUP_NAME // .AZURE_RESOURCE_GROUP // empty') | |
| [[ -z "$RG_NAME" ]] && export RG_NAME="${{ env.RESOURCE_GROUP_NAME }}" | |
| echo "RG_NAME=$RG_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 "$RG_NAME" ]]; then | |
| az webapp config appsettings set -g "$RG_NAME" -n "$WEB_APP_NAME" --settings AUTH_ENABLED=false | |
| else | |
| echo "Warning: Could not disable AUTH_ENABLED - WEB_APP_NAME or RG_NAME not found" | |
| fi | |
| sleep 30 | |
| - name: Deploy Infra and Import Sample Data | |
| run: | | |
| set -e | |
| az account set --subscription "${{ secrets.AZURE_SUBSCRIPTION_ID }}" | |
| echo "Running post-deployment script..." | |
| bash ./infra/scripts/add_cosmosdb_access.sh \ | |
| "${{ env.RG_NAME }}" \ | |
| "${{ env.COSMOS_DB_ACCOUNT_NAME }}" \ | |
| "${{ secrets.AZURE_CLIENT_ID }}" | |
| bash ./infra/scripts/copy_kb_files.sh \ | |
| "${{ env.STORAGE_ACCOUNT }}" \ | |
| "${{ env.STORAGE_CONTAINER }}" \ | |
| "" \ | |
| "${{ secrets.AZURE_CLIENT_ID }}" | |
| bash ./infra/scripts/run_create_index_scripts.sh \ | |
| "${{ env.KEYVAULT_NAME }}" \ | |
| "" \ | |
| "${{ secrets.AZURE_CLIENT_ID }}" \ | |
| "${{ env.RG_NAME }}" \ | |
| "${{ env.SQL_SERVER_NAME }}" \ | |
| "${{ env.SEARCH_SERVICE_NAME }}" \ | |
| "${{ env.AI_FOUNDRY_RESOURCE_ID}}" | |
| user_roles_json='[ | |
| {"clientId":"${{ env.CLIENT_ID }}","displayName":"${{ env.CLIENT_NAME }}","role":"db_datareader"}, | |
| {"clientId":"${{ env.CLIENT_ID }}","displayName":"${{ env.CLIENT_NAME }}","role":"db_owner"} | |
| ]' | |
| bash ./infra/scripts/add_user_scripts/create_sql_user_and_role.sh \ | |
| "${{ env.SQL_SERVER_NAME }}.database.windows.net" \ | |
| "${{ env.SQL_DATABASE }}" \ | |
| "$user_roles_json" \ | |
| "${{ secrets.AZURE_CLIENT_ID }}" | |
| echo "=== Post-Deployment Script Completed Successfully ===" | |
| - name: Get AI Services name and store in variable | |
| if: always() && steps.generate_env_name.outcome == 'success' | |
| id: get_ai_services_name | |
| run: | | |
| set -e | |
| echo "Getting AI Services name..." | |
| # Get the AI Services name | |
| ai_services_name=$(az cognitiveservices account list -g ${{ env.RESOURCE_GROUP_NAME }} --query "[0].name" -o tsv) | |
| if [ -z "$ai_services_name" ]; then | |
| echo "No AI Services resource found in the resource group." | |
| echo "AI_SERVICES_NAME=" >> $GITHUB_OUTPUT | |
| else | |
| echo "AI_SERVICES_NAME=${ai_services_name}" >> $GITHUB_OUTPUT | |
| echo "Found AI Services resource: $ai_services_name" | |
| fi | |
| - name: List KeyVaults and Store in Array | |
| if: always() && steps.generate_env_name.outcome == 'success' | |
| id: list_keyvaults | |
| run: | | |
| set -e | |
| echo "Listing all KeyVaults in the resource group ${{ env.RESOURCE_GROUP_NAME }}..." | |
| # Get the list of KeyVaults in the specified resource group | |
| keyvaults=$(az resource list --resource-group ${{ env.RESOURCE_GROUP_NAME }} --query "[?type=='Microsoft.KeyVault/vaults'].name" -o tsv) | |
| if [ -z "$keyvaults" ]; then | |
| echo "No KeyVaults found in resource group ${{ env.RESOURCE_GROUP_NAME }}." | |
| echo "KEYVAULTS=[]" >> $GITHUB_OUTPUT # If no KeyVaults found, set an empty array | |
| else | |
| echo "KeyVaults found: $keyvaults" | |
| # Format the list into an array with proper formatting (no trailing comma) | |
| keyvault_array="[" | |
| first=true | |
| for kv in $keyvaults; do | |
| if [ "$first" = true ]; then | |
| keyvault_array="$keyvault_array\"$kv\"" | |
| first=false | |
| else | |
| keyvault_array="$keyvault_array,\"$kv\"" | |
| fi | |
| done | |
| keyvault_array="$keyvault_array]" | |
| # Output the formatted array and save it to the job output | |
| echo "KEYVAULTS=$keyvault_array" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Set Deployment Status | |
| id: deployment_status | |
| if: always() | |
| run: | | |
| if [ "${{ job.status }}" == "success" ]; then | |
| echo "SUCCESS=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "SUCCESS=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Logout | |
| if: always() | |
| run: az logout | |
| e2e-test: | |
| needs: deploy | |
| if: needs.deploy.outputs.DEPLOYMENT_SUCCESS == 'true' | |
| uses: ./.github/workflows/test_automation.yml | |
| with: | |
| CA_WEB_URL: ${{ needs.deploy.outputs.WEBAPP_URL }} | |
| secrets: inherit | |
| cleanup: | |
| if: always() | |
| needs: [deploy, e2e-test] | |
| runs-on: ubuntu-latest | |
| env: | |
| RESOURCE_GROUP_NAME: ${{ needs.deploy.outputs.RESOURCE_GROUP_NAME }} | |
| AI_SERVICES_NAME: ${{ needs.deploy.outputs.AI_SERVICES_NAME }} | |
| KEYVAULTS: ${{ needs.deploy.outputs.KEYVAULTS }} | |
| AZURE_LOCATION: ${{ needs.deploy.outputs.AZURE_LOCATION }} | |
| SOLUTION_PREFIX: ${{ needs.deploy.outputs.SOLUTION_PREFIX }} | |
| steps: | |
| - name: Setup Azure CLI | |
| run: curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash | |
| - name: Login to Azure | |
| run: | | |
| az login --service-principal -u ${{ secrets.AZURE_CLIENT_ID }} -p ${{ secrets.AZURE_CLIENT_SECRET }} --tenant ${{ secrets.AZURE_TENANT_ID }} | |
| az account set --subscription ${{ secrets.AZURE_SUBSCRIPTION_ID }} | |
| # Set environment variables for azd authentication | |
| echo "AZURE_CLIENT_ID=${{ secrets.AZURE_CLIENT_ID }}" >> $GITHUB_ENV | |
| echo "AZURE_CLIENT_SECRET=${{ secrets.AZURE_CLIENT_SECRET }}" >> $GITHUB_ENV | |
| echo "AZURE_TENANT_ID=${{ secrets.AZURE_TENANT_ID }}" >> $GITHUB_ENV | |
| echo "AZURE_SUBSCRIPTION_ID=${{ secrets.AZURE_SUBSCRIPTION_ID }}" >> $GITHUB_ENV | |
| - name: Cleanup using azd down | |
| if: always() | |
| run: | | |
| set -e | |
| echo "Cleaning up resources using azd down..." | |
| # Install azd (Azure Developer CLI) | |
| curl -fsSL https://aka.ms/install-azd.sh | bash | |
| # Check if resource group exists before attempting cleanup | |
| echo "Resource group name: ${{ env.RESOURCE_GROUP_NAME }}" | |
| if [ -z "${{ env.RESOURCE_GROUP_NAME }}" ]; then | |
| echo "Resource group name is empty. Skipping cleanup." | |
| exit 0 | |
| fi | |
| rg_exists=$(az group exists --name "${{ env.RESOURCE_GROUP_NAME }}") | |
| if [ "$rg_exists" = "true" ]; then | |
| echo "Resource group exists. Cleaning up with azd down..." | |
| # Extract environment name from resource group name (remove rg- prefix) | |
| ENV_NAME=$(echo "${{ env.RESOURCE_GROUP_NAME }}" | sed 's/^rg-//') | |
| # azd authentication environment variables are already set in the previous step | |
| # Try to clean up using azd down (if environment exists) | |
| if azd env list | grep -q "$ENV_NAME"; then | |
| echo "Found azd environment: $ENV_NAME" | |
| azd env select "$ENV_NAME" | |
| azd down --force --purge --no-prompt | |
| else | |
| echo "No azd environment found for $ENV_NAME, falling back to resource group deletion" | |
| az group delete \ | |
| --name "${{ env.RESOURCE_GROUP_NAME }}" \ | |
| --yes \ | |
| --no-wait | |
| fi | |
| echo "Resource cleanup initiated for: ${{ env.RESOURCE_GROUP_NAME }}" | |
| else | |
| echo "Resource group does not exist." | |
| fi | |
| - name: Wait for resource deletion to complete | |
| if: always() | |
| run: | | |
| # Check if resource group name is available | |
| if [ -z "${{ env.RESOURCE_GROUP_NAME }}" ]; then | |
| echo "Resource group name is empty. Skipping resource check." | |
| exit 0 | |
| fi | |
| # List of keyvaults | |
| KEYVAULTS="${{ env.KEYVAULTS }}" | |
| # Remove the surrounding square brackets and quotes, if they exist | |
| stripped_keyvaults=$(echo "$KEYVAULTS" | sed 's/\[\|\]//g' | sed 's/"//g') | |
| # Convert the comma-separated string into an array | |
| IFS=',' read -r -a resources_to_check <<< "$stripped_keyvaults" | |
| echo "List of resources to check: ${resources_to_check[@]}" | |
| # Check if resource group still exists before listing resources | |
| rg_exists=$(az group exists --name "${{ env.RESOURCE_GROUP_NAME }}") | |
| if [ "$rg_exists" = "false" ]; then | |
| echo "Resource group no longer exists. Skipping resource check." | |
| exit 0 | |
| fi | |
| # Get the list of resources in YAML format | |
| resource_list=$(az resource list --resource-group "${{ env.RESOURCE_GROUP_NAME }}" --output yaml || echo "") | |
| # Maximum number of retries | |
| max_retries=3 | |
| # Retry intervals in seconds (30, 60, 120) | |
| retry_intervals=(30 60 120) | |
| # Retry mechanism to check resources | |
| retries=0 | |
| while true; do | |
| resource_found=false | |
| # Check if resource group still exists | |
| rg_exists=$(az group exists --name "${{ env.RESOURCE_GROUP_NAME }}") | |
| if [ "$rg_exists" = "false" ]; then | |
| echo "Resource group no longer exists. Exiting resource check." | |
| break | |
| fi | |
| # Iterate through the resources to check | |
| for resource in "${resources_to_check[@]}"; do | |
| # Skip empty resource names | |
| if [ -z "$resource" ]; then | |
| continue | |
| fi | |
| echo "Checking resource: $resource" | |
| if echo "$resource_list" | grep -q "name: $resource"; then | |
| echo "Resource '$resource' exists in the resource group." | |
| resource_found=true | |
| else | |
| echo "Resource '$resource' does not exist in the resource group." | |
| fi | |
| done | |
| # If any resource exists, retry | |
| if [ "$resource_found" = true ]; then | |
| retries=$((retries + 1)) | |
| if [ "$retries" -ge "$max_retries" ]; then | |
| echo "Maximum retry attempts reached. Exiting." | |
| break | |
| else | |
| # Wait for the appropriate interval for the current retry | |
| echo "Waiting for ${retry_intervals[$retries-1]} seconds before retrying..." | |
| sleep ${retry_intervals[$retries-1]} | |
| # Refresh resource list | |
| resource_list=$(az resource list --resource-group "${{ env.RESOURCE_GROUP_NAME }}" --output yaml || echo "") | |
| fi | |
| else | |
| echo "No resources found. Exiting." | |
| break | |
| fi | |
| done | |
| - name: Purging the Resources | |
| if: always() | |
| run: | | |
| set -e | |
| # Check if resource group name is available | |
| if [ -z "${{ env.RESOURCE_GROUP_NAME }}" ]; then | |
| echo "Resource group name is empty. Skipping resource purging." | |
| exit 0 | |
| fi | |
| # Purge AI Services | |
| if [ -z "${{ env.AI_SERVICES_NAME }}" ]; then | |
| echo "AI_SERVICES_NAME is not set. Skipping AI Services purge." | |
| else | |
| echo "Purging AI Services..." | |
| if [ -n "$(az cognitiveservices account list-deleted --query "[?name=='${{ env.AI_SERVICES_NAME }}']" -o tsv)" ]; then | |
| echo "AI Services '${{ env.AI_SERVICES_NAME }}' is soft-deleted. Proceeding to purge..." | |
| az cognitiveservices account purge --location "${{ env.AZURE_LOCATION }}" --resource-group "${{ env.RESOURCE_GROUP_NAME }}" --name "${{ env.AI_SERVICES_NAME }}" | |
| else | |
| echo "AI Services '${{ env.AI_SERVICES_NAME }}' is not soft-deleted. No action taken." | |
| fi | |
| fi | |
| # Ensure KEYVAULTS is properly formatted as a comma-separated string | |
| KEYVAULTS="${{ env.KEYVAULTS }}" | |
| # Check if KEYVAULTS is empty or null | |
| if [ -z "$KEYVAULTS" ] || [ "$KEYVAULTS" = "[]" ]; then | |
| echo "No KeyVaults to purge." | |
| exit 0 | |
| fi | |
| # Remove the surrounding square brackets and quotes, if they exist | |
| stripped_keyvaults=$(echo "$KEYVAULTS" | sed 's/\[\|\]//g' | sed 's/"//g') | |
| # Convert the comma-separated string into an array | |
| IFS=',' read -r -a keyvault_array <<< "$stripped_keyvaults" | |
| echo "Using KeyVaults Array..." | |
| for keyvault_name in "${keyvault_array[@]}"; do | |
| # Skip empty keyvault names | |
| if [ -z "$keyvault_name" ]; then | |
| continue | |
| fi | |
| echo "Processing KeyVault: $keyvault_name" | |
| # Check if the KeyVault is soft-deleted | |
| deleted_vaults=$(az keyvault list-deleted --query "[?name=='$keyvault_name']" -o json --subscription ${{ env.AZURE_SUBSCRIPTION_ID }}) | |
| # If the KeyVault is found in the soft-deleted state, purge it | |
| if [ "$(echo "$deleted_vaults" | jq length)" -gt 0 ]; then | |
| echo "KeyVault '$keyvault_name' is soft-deleted. Proceeding to purge..." | |
| az keyvault purge --name "$keyvault_name" --no-wait | |
| else | |
| echo "KeyVault '$keyvault_name' is not soft-deleted. No action taken." | |
| fi | |
| done | |
| echo "Resource purging completed successfully" | |
| - name: Logout | |
| if: always() | |
| run: az logout | |
| - name: Notify on Failure | |
| if: failure() || needs.deploy.result == 'failure' || needs.e2e-test.result == 'failure' | |
| run: | | |
| RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" | |
| # Construct the email body | |
| EMAIL_BODY=$(cat <<EOF | |
| { | |
| "body": "<p>Dear Team,</p><p>We would like to inform you that the Build-your-own-copilot-Solution-Accelerator(Client Advisior) Automation process has encountered an issue and has failed to complete successfully.</p><p><strong>Build URL:</strong> ${RUN_URL}<br> ${OUTPUT}</p><p>Please investigate the matter at your earliest convenience.</p><p>Best regards,<br>Your Automation Team</p>" | |
| } | |
| EOF | |
| ) | |
| # Send the notification | |
| curl -X POST "${{ secrets.LOGIC_APP_URL }}" \ | |
| -H "Content-Type: application/json" \ | |
| -d "$EMAIL_BODY" || echo "Failed to send notification" |