diff --git a/.github/workflows/deploy-orchestrator.yml b/.github/workflows/deploy-orchestrator.yml
index 8a9f90838..9d860ad32 100644
--- a/.github/workflows/deploy-orchestrator.yml
+++ b/.github/workflows/deploy-orchestrator.yml
@@ -104,9 +104,25 @@ jobs:
TEST_SUITE: ${{ inputs.trigger_type == 'workflow_dispatch' && inputs.run_e2e_tests || 'GoldenPath-Testing' }}
secrets: inherit
+ cleanup-deployment:
+ if: "!cancelled() && needs.deploy.outputs.RESOURCE_GROUP_NAME != '' && inputs.existing_webapp_url == '' && (inputs.trigger_type != 'workflow_dispatch' || inputs.cleanup_resources)"
+ needs: [docker-build, deploy, e2e-test]
+ uses: ./.github/workflows/job-cleanup-deployment.yml
+ with:
+ runner_os: ${{ inputs.runner_os }}
+ trigger_type: ${{ inputs.trigger_type }}
+ cleanup_resources: ${{ inputs.cleanup_resources }}
+ existing_webapp_url: ${{ inputs.existing_webapp_url }}
+ RESOURCE_GROUP_NAME: ${{ needs.deploy.outputs.RESOURCE_GROUP_NAME }}
+ AZURE_LOCATION: ${{ needs.deploy.outputs.AZURE_LOCATION }}
+ AZURE_ENV_OPENAI_LOCATION: ${{ needs.deploy.outputs.AZURE_ENV_OPENAI_LOCATION }}
+ ENV_NAME: ${{ needs.deploy.outputs.ENV_NAME }}
+ IMAGE_TAG: ${{ needs.deploy.outputs.IMAGE_TAG }}
+ secrets: inherit
+
send-notification:
if: "!cancelled()"
- needs: [docker-build, deploy, e2e-test]
+ needs: [docker-build, deploy, e2e-test, cleanup-deployment]
uses: ./.github/workflows/job-send-notification.yml
with:
trigger_type: ${{ inputs.trigger_type }}
@@ -121,20 +137,5 @@ jobs:
QUOTA_FAILED: ${{ needs.deploy.outputs.QUOTA_FAILED }}
TEST_SUCCESS: ${{ needs.e2e-test.outputs.TEST_SUCCESS }}
TEST_REPORT_URL: ${{ needs.e2e-test.outputs.TEST_REPORT_URL }}
- secrets: inherit
-
- cleanup-deployment:
- if: "!cancelled() && needs.deploy.outputs.RESOURCE_GROUP_NAME != '' && inputs.existing_webapp_url == '' && (inputs.trigger_type != 'workflow_dispatch' || inputs.cleanup_resources)"
- needs: [docker-build, deploy, e2e-test]
- uses: ./.github/workflows/job-cleanup-deployment.yml
- with:
- runner_os: ${{ inputs.runner_os }}
- trigger_type: ${{ inputs.trigger_type }}
- cleanup_resources: ${{ inputs.cleanup_resources }}
- existing_webapp_url: ${{ inputs.existing_webapp_url }}
- RESOURCE_GROUP_NAME: ${{ needs.deploy.outputs.RESOURCE_GROUP_NAME }}
- AZURE_LOCATION: ${{ needs.deploy.outputs.AZURE_LOCATION }}
- AZURE_ENV_OPENAI_LOCATION: ${{ needs.deploy.outputs.AZURE_ENV_OPENAI_LOCATION }}
- ENV_NAME: ${{ needs.deploy.outputs.ENV_NAME }}
- IMAGE_TAG: ${{ needs.deploy.outputs.IMAGE_TAG }}
+ cleanup_result: ${{ needs.cleanup-deployment.result }}
secrets: inherit
diff --git a/.github/workflows/job-send-notification.yml b/.github/workflows/job-send-notification.yml
index 5b062a89e..f86f3a9db 100644
--- a/.github/workflows/job-send-notification.yml
+++ b/.github/workflows/job-send-notification.yml
@@ -1,4 +1,5 @@
name: Send Notification Job
+
on:
workflow_call:
inputs:
@@ -32,7 +33,8 @@ on:
type: string
e2e_test_result:
description: 'E2E test job result (success, failure, skipped)'
- required: true
+ required: false
+ default: ''
type: string
CONTAINER_WEB_APPURL:
description: 'Container Web App URL'
@@ -59,6 +61,11 @@ on:
required: false
default: ''
type: string
+ cleanup_result:
+ description: 'Cleanup job result (success, failure, skipped)'
+ required: false
+ default: 'skipped'
+ type: string
env:
GPT_MIN_CAPACITY: 100
@@ -74,183 +81,68 @@ jobs:
env:
accelerator_name: "MACAE V4"
steps:
- - name: Validate Workflow Input Parameters
- shell: bash
- env:
- INPUT_TRIGGER_TYPE: ${{ inputs.trigger_type }}
- INPUT_WAF_ENABLED: ${{ inputs.waf_enabled }}
- INPUT_EXP: ${{ inputs.EXP }}
- INPUT_RUN_E2E_TESTS: ${{ inputs.run_e2e_tests }}
- INPUT_EXISTING_WEBAPP_URL: ${{ inputs.existing_webapp_url }}
- INPUT_DEPLOY_RESULT: ${{ inputs.deploy_result }}
- INPUT_E2E_TEST_RESULT: ${{ inputs.e2e_test_result }}
- INPUT_CONTAINER_WEB_APPURL: ${{ inputs.CONTAINER_WEB_APPURL }}
- INPUT_RESOURCE_GROUP_NAME: ${{ inputs.RESOURCE_GROUP_NAME }}
- INPUT_QUOTA_FAILED: ${{ inputs.QUOTA_FAILED }}
- INPUT_TEST_SUCCESS: ${{ inputs.TEST_SUCCESS }}
- INPUT_TEST_REPORT_URL: ${{ inputs.TEST_REPORT_URL }}
- run: |
- echo "🔍 Validating workflow input parameters..."
- VALIDATION_FAILED=false
-
- # Validate trigger_type (required)
- if [[ -z "$INPUT_TRIGGER_TYPE" ]]; then
- echo "❌ ERROR: trigger_type is required but not provided"
- VALIDATION_FAILED=true
- else
- echo "✅ trigger_type: '$INPUT_TRIGGER_TYPE' is valid"
- fi
-
- # Validate waf_enabled (boolean)
- if [[ "$INPUT_WAF_ENABLED" != "true" && "$INPUT_WAF_ENABLED" != "false" ]]; then
- echo "❌ ERROR: waf_enabled must be 'true' or 'false', got: '$INPUT_WAF_ENABLED'"
- VALIDATION_FAILED=true
- else
- echo "✅ waf_enabled: '$INPUT_WAF_ENABLED' is valid"
- fi
-
- # Validate EXP (boolean)
- if [[ "$INPUT_EXP" != "true" && "$INPUT_EXP" != "false" ]]; then
- echo "❌ ERROR: EXP must be 'true' or 'false', got: '$INPUT_EXP'"
- VALIDATION_FAILED=true
- else
- echo "✅ EXP: '$INPUT_EXP' is valid"
- fi
-
- # Validate run_e2e_tests (specific allowed values)
- if [[ -n "$INPUT_RUN_E2E_TESTS" ]]; then
- ALLOWED_VALUES=("None" "GoldenPath-Testing" "Smoke-Testing")
- if [[ ! " ${ALLOWED_VALUES[@]} " =~ " ${INPUT_RUN_E2E_TESTS} " ]]; then
- echo "❌ ERROR: run_e2e_tests '$INPUT_RUN_E2E_TESTS' is invalid. Allowed values: ${ALLOWED_VALUES[*]}"
- VALIDATION_FAILED=true
- else
- echo "✅ run_e2e_tests: '$INPUT_RUN_E2E_TESTS' is valid"
- fi
- fi
-
- # Validate existing_webapp_url (must start with https if provided)
- if [[ -n "$INPUT_EXISTING_WEBAPP_URL" ]]; then
- if [[ ! "$INPUT_EXISTING_WEBAPP_URL" =~ ^https:// ]]; then
- echo "❌ ERROR: existing_webapp_url must start with 'https://', got: '$INPUT_EXISTING_WEBAPP_URL'"
- VALIDATION_FAILED=true
- else
- echo "✅ existing_webapp_url: '$INPUT_EXISTING_WEBAPP_URL' is valid"
- fi
- fi
-
- # Validate deploy_result (must be specific values if provided)
- if [[ -n "$INPUT_DEPLOY_RESULT" ]]; then
- ALLOWED_DEPLOY_RESULTS=("success" "failure" "skipped")
- if [[ ! " ${ALLOWED_DEPLOY_RESULTS[@]} " =~ " ${INPUT_DEPLOY_RESULT} " ]]; then
- echo "❌ ERROR: deploy_result '$INPUT_DEPLOY_RESULT' is invalid. Allowed values: ${ALLOWED_DEPLOY_RESULTS[*]}"
- VALIDATION_FAILED=true
- else
- echo "✅ deploy_result: '$INPUT_DEPLOY_RESULT' is valid"
- fi
- fi
-
- # Validate e2e_test_result (must be specific values if provided)
- if [[ -n "$INPUT_E2E_TEST_RESULT" ]]; then
- ALLOWED_TEST_RESULTS=("success" "failure" "skipped")
- if [[ ! " ${ALLOWED_TEST_RESULTS[@]} " =~ " ${INPUT_E2E_TEST_RESULT} " ]]; then
- echo "❌ ERROR: e2e_test_result '$INPUT_E2E_TEST_RESULT' is invalid. Allowed values: ${ALLOWED_TEST_RESULTS[*]}"
- VALIDATION_FAILED=true
- else
- echo "✅ e2e_test_result: '$INPUT_E2E_TEST_RESULT' is valid"
- fi
- fi
-
- # Validate CONTAINER_WEB_APPURL (must start with https if provided)
- if [[ -n "$INPUT_CONTAINER_WEB_APPURL" ]]; then
- if [[ ! "$INPUT_CONTAINER_WEB_APPURL" =~ ^https:// ]]; then
- echo "❌ ERROR: CONTAINER_WEB_APPURL must start with 'https://', got: '$INPUT_CONTAINER_WEB_APPURL'"
- VALIDATION_FAILED=true
- else
- echo "✅ CONTAINER_WEB_APPURL: '$INPUT_CONTAINER_WEB_APPURL' is valid"
- fi
- fi
-
- # Validate RESOURCE_GROUP_NAME (Azure resource group naming convention if provided)
- if [[ -n "$INPUT_RESOURCE_GROUP_NAME" ]]; then
- if [[ ! "$INPUT_RESOURCE_GROUP_NAME" =~ ^[a-zA-Z0-9._\(\)-]+$ ]] || [[ "$INPUT_RESOURCE_GROUP_NAME" =~ \.$ ]]; then
- echo "❌ ERROR: RESOURCE_GROUP_NAME '$INPUT_RESOURCE_GROUP_NAME' is invalid. Must contain only alphanumerics, periods, underscores, hyphens, and parentheses. Cannot end with period."
- VALIDATION_FAILED=true
- elif [[ ${#INPUT_RESOURCE_GROUP_NAME} -gt 90 ]]; then
- echo "❌ ERROR: RESOURCE_GROUP_NAME '$INPUT_RESOURCE_GROUP_NAME' exceeds 90 characters"
- VALIDATION_FAILED=true
- else
- echo "✅ RESOURCE_GROUP_NAME: '$INPUT_RESOURCE_GROUP_NAME' is valid"
- fi
- fi
-
- # Validate QUOTA_FAILED (must be 'true', 'false', or empty string)
- if [[ "$INPUT_QUOTA_FAILED" != "true" && "$INPUT_QUOTA_FAILED" != "false" && "$INPUT_QUOTA_FAILED" != "" ]]; then
- echo "❌ ERROR: QUOTA_FAILED must be 'true', 'false', or empty string, got: '$INPUT_QUOTA_FAILED'"
- VALIDATION_FAILED=true
- else
- echo "✅ QUOTA_FAILED: '$INPUT_QUOTA_FAILED' is valid"
- fi
-
- # Validate TEST_SUCCESS (must be 'true' or 'false' or empty)
- if [[ -n "$INPUT_TEST_SUCCESS" ]]; then
- if [[ "$INPUT_TEST_SUCCESS" != "true" && "$INPUT_TEST_SUCCESS" != "false" ]]; then
- echo "❌ ERROR: TEST_SUCCESS must be 'true', 'false', or empty, got: '$INPUT_TEST_SUCCESS'"
- VALIDATION_FAILED=true
- else
- echo "✅ TEST_SUCCESS: '$INPUT_TEST_SUCCESS' is valid"
- fi
- fi
-
- # Validate TEST_REPORT_URL (must start with https if provided)
- if [[ -n "$INPUT_TEST_REPORT_URL" ]]; then
- if [[ ! "$INPUT_TEST_REPORT_URL" =~ ^https:// ]]; then
- echo "❌ ERROR: TEST_REPORT_URL must start with 'https://', got: '$INPUT_TEST_REPORT_URL'"
- VALIDATION_FAILED=true
- else
- echo "✅ TEST_REPORT_URL: '$INPUT_TEST_REPORT_URL' is valid"
- fi
- fi
-
- # Fail workflow if any validation failed
- if [[ "$VALIDATION_FAILED" == "true" ]]; then
- echo ""
- echo "❌ Parameter validation failed. Please correct the errors above and try again."
- exit 1
- fi
-
- echo ""
- echo "✅ All input parameters validated successfully!"
-
- name: Determine Test Suite Display Name
id: test_suite
shell: bash
+ env:
+ RUN_E2E_TESTS: ${{ env.RUN_E2E_TESTS }}
run: |
- if [ "${{ env.RUN_E2E_TESTS }}" = "GoldenPath-Testing" ]; then
+ if [ "$RUN_E2E_TESTS" = "GoldenPath-Testing" ]; then
TEST_SUITE_NAME="Golden Path Testing"
- elif [ "${{ env.RUN_E2E_TESTS }}" = "Smoke-Testing" ]; then
+ elif [ "$RUN_E2E_TESTS" = "Smoke-Testing" ]; then
TEST_SUITE_NAME="Smoke Testing"
- elif [ "${{ env.RUN_E2E_TESTS }}" = "None" ]; then
+ elif [ "$RUN_E2E_TESTS" = "None" ]; then
TEST_SUITE_NAME="None"
else
- TEST_SUITE_NAME="${{ env.RUN_E2E_TESTS }}"
+ TEST_SUITE_NAME="$RUN_E2E_TESTS"
fi
echo "TEST_SUITE_NAME=$TEST_SUITE_NAME" >> $GITHUB_OUTPUT
echo "Test Suite: $TEST_SUITE_NAME"
+ - name: Determine Cleanup Status
+ id: cleanup
+ shell: bash
+ env:
+ CLEANUP_RESULT: ${{ inputs.cleanup_result }}
+ run: |
+ case "$CLEANUP_RESULT" in
+ success) echo "CLEANUP_STATUS=✅ SUCCESS" >> $GITHUB_OUTPUT ;;
+ failure) echo "CLEANUP_STATUS=❌ FAILED (Needs Manual Cleanup)" >> $GITHUB_OUTPUT ;;
+ *) echo "CLEANUP_STATUS=⏭️ SKIPPED (Needs Manual Cleanup)" >> $GITHUB_OUTPUT ;;
+ esac
+
+ - name: Determine Configuration Label
+ id: config
+ shell: bash
+ env:
+ WAF_ENABLED: ${{ env.WAF_ENABLED }}
+ EXP: ${{ env.EXP }}
+ run: |
+ WAF_LABEL=$( [ "$WAF_ENABLED" = "true" ] && echo "WAF" || echo "Non-WAF" )
+ EXP_LABEL=$( [ "$EXP" = "true" ] && echo "EXP" || echo "Non-EXP" )
+ echo "CONFIG_LABEL=${WAF_LABEL} + ${EXP_LABEL}" >> $GITHUB_OUTPUT
+
- name: Send Quota Failure Notification
if: inputs.deploy_result == 'failure' && inputs.QUOTA_FAILED == 'true'
shell: bash
+ env:
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_RUN_ID: ${{ github.run_id }}
+ ACCELERATOR_NAME: ${{ env.accelerator_name }}
+ LOGICAPP_URL: ${{ secrets.EMAILNOTIFICATION_LOGICAPP_URL_TA }}
+ CLEANUP_STATUS: ${{ steps.cleanup.outputs.CLEANUP_STATUS }}
+ CONFIG_LABEL: ${{ steps.config.outputs.CONFIG_LABEL }}
run: |
- RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
+ RUN_URL="https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
EMAIL_BODY=$(cat <
We would like to inform you that the ${{ env.accelerator_name }} deployment has failed due to insufficient quota in the requested regions.
Issue Details:
• Quota check failed for GPT model
• Required GPT Capacity: ${{ env.GPT_MIN_CAPACITY }}
• Checked Regions: ${{ vars.AZURE_REGIONS }}
Run URL: ${RUN_URL}
Please resolve the quota issue and retry the deployment.
Best regards,
Your Automation Team
Dear Team,
We would like to inform you that the ${ACCELERATOR_NAME} deployment has failed due to insufficient quota.
Status Summary:
| Stage | Status |
|---|---|
| Deployment | ❌ FAILED (Insufficient Quota) |
| E2E Tests | ⏭️ SKIPPED |
| Cleanup | ${CLEANUP_STATUS} |
Configuration: ${CONFIG_LABEL}
Run URL: ${RUN_URL}
Please resolve the quota issue and retry the deployment.
Best regards,
Your Automation Team
We would like to inform you that the ${{ env.accelerator_name }} deployment process has encountered an issue and has failed to complete successfully.
Deployment Details:
• Resource Group: ${RESOURCE_GROUP}
• WAF Enabled: ${{ env.WAF_ENABLED }}
• EXP Enabled: ${{ env.EXP }}
Run URL: ${RUN_URL}
Please investigate the deployment failure at your earliest convenience.
Best regards,
Your Automation Team
Dear Team,
We would like to inform you that the ${ACCELERATOR_NAME} deployment has failed.
Status Summary:
| Stage | Status |
|---|---|
| Deployment | ❌ FAILED (Deployment Issue) |
| E2E Tests | ⏭️ SKIPPED |
| Cleanup | ${CLEANUP_STATUS} |
Deployment Details:
• Resource Group: ${RESOURCE_GROUP}
Configuration: ${CONFIG_LABEL}
Run URL: ${RUN_URL}
Please investigate the deployment failure at your earliest convenience.
Best regards,
Your Automation Team
We would like to inform you that the ${{ env.accelerator_name }} deployment has completed successfully.
Deployment Details:
• Resource Group: ${RESOURCE_GROUP}
• Web App URL: ${WEBAPP_URL}
• E2E Tests: Skipped (as configured)
Configuration:
• WAF Enabled: ${{ env.WAF_ENABLED }}
• EXP Enabled: ${{ env.EXP }}
Run URL: ${RUN_URL}
Best regards,
Your Automation Team
Dear Team,
We would like to inform you that the ${ACCELERATOR_NAME} deployment has completed successfully.
Status Summary:
| Stage | Status |
|---|---|
| Deployment | ✅ SUCCESS |
| E2E Tests | ⏭️ SKIPPED |
| Cleanup | ${CLEANUP_STATUS} |
Deployment Details:
• Resource Group: ${RESOURCE_GROUP}
• Web App URL: ${WEBAPP_URL}
Configuration: ${CONFIG_LABEL}
Run URL: ${RUN_URL}
Best regards,
Your Automation Team
We would like to inform you that the ${{ env.accelerator_name }} deployment and testing process has completed successfully.
Deployment Details:
• Resource Group: ${RESOURCE_GROUP}
• Web App URL: ${WEBAPP_URL}
• E2E Tests: Passed ✅
• Test Suite: ${TEST_SUITE_NAME}
• Test Report: View Report
Configuration:
• WAF Enabled: ${{ env.WAF_ENABLED }}
• EXP Enabled: ${{ env.EXP }}
Run URL: ${RUN_URL}
Best regards,
Your Automation Team
Dear Team,
We would like to inform you that the ${ACCELERATOR_NAME} deployment and test automation has completed successfully.
Status Summary:
| Stage | Status |
|---|---|
| Deployment | ✅ SUCCESS |
| E2E Tests | ✅ SUCCESS |
| Cleanup | ${CLEANUP_STATUS} |
Deployment Details:
• Resource Group: ${RESOURCE_GROUP}
• Web App URL: ${WEBAPP_URL}
• Test Suite: ${TEST_SUITE_NAME}
• Test Report: View Report
Configuration: ${CONFIG_LABEL}
Run URL: ${RUN_URL}
Best regards,
Your Automation Team
We would like to inform you that ${{ env.accelerator_name }} accelerator test automation process has encountered issues and failed to complete successfully.
Deployment Details:
• Resource Group: ${RESOURCE_GROUP}
• Web App URL: ${WEBAPP_URL}
• Deployment Status: ✅ Success
• E2E Tests: ❌ Failed
• Test Suite: ${TEST_SUITE_NAME}
Test Details:
• Test Report: View Report
Run URL: ${RUN_URL}
Please investigate the matter at your earliest convenience.
Best regards,
Your Automation Team
Dear Team,
We would like to inform you that ${ACCELERATOR_NAME} test automation has failed.
Status Summary:
| Stage | Status |
|---|---|
| Deployment | ✅ SUCCESS |
| E2E Tests | ❌ FAILED |
| Cleanup | ${CLEANUP_STATUS} |
Deployment Details:
• Resource Group: ${RESOURCE_GROUP}
• Web App URL: ${WEBAPP_URL}
• Test Suite: ${TEST_SUITE_NAME}
• Test Report: View Report
Configuration: ${CONFIG_LABEL}
Run URL: ${RUN_URL}
Please investigate the matter at your earliest convenience.
Best regards,
Your Automation Team
The ${{ env.accelerator_name }} pipeline executed against the specified target URL and testing process has completed successfully.
Test Results:
• Status: ✅ Passed
• Test Suite: ${TEST_SUITE_NAME}
${TEST_REPORT_URL:+• Test Report: View Report}
• Target URL: ${EXISTING_URL}
Deployment: Skipped
Run URL: ${RUN_URL}
Best regards,
Your Automation Team
Dear Team,
The ${ACCELERATOR_NAME} pipeline executed against the specified Target URL and test automation has completed successfully.
Status Summary:
| Stage | Status |
|---|---|
| Deployment | ⏭️ SKIPPED (Tests executed on Pre-deployed RG) |
| E2E Tests | ✅ SUCCESS |
| Cleanup | ${CLEANUP_STATUS} |
Test Results:
• Test Suite: ${TEST_SUITE_NAME}
${TEST_REPORT_URL:+• Test Report: View Report}
• Target URL: ${EXISTING_URL}
Run URL: ${RUN_URL}
Best regards,
Your Automation Team
The ${{ env.accelerator_name }} pipeline executed against the specified target URL and the test automation has encountered issues and failed to complete successfully.
Failure Details:
• Target URL: ${EXISTING_URL}
${TEST_REPORT_URL:+• Test Report: View Report}
• Test Suite: ${TEST_SUITE_NAME}
• Deployment: Skipped
Run URL: ${RUN_URL}
Best regards,
Your Automation Team
Dear Team,
The ${ACCELERATOR_NAME} pipeline executed against the specified Target URL and test automation has failed.
Status Summary:
| Stage | Status |
|---|---|
| Deployment | ⏭️ SKIPPED (Tests executed on Pre-deployed RG) |
| E2E Tests | ❌ FAILED |
| Cleanup | ${CLEANUP_STATUS} |
Failure Details:
• Target URL: ${EXISTING_URL}
${TEST_REPORT_URL:+• Test Report: View Report}
• Test Suite: ${TEST_SUITE_NAME}
Run URL: ${RUN_URL}
Best regards,
Your Automation Team