Skip to content

Commit 465a96c

Browse files
Merge pull request #253 from microsoft/hotfix
feat: merging the changes from hotfix to main
2 parents 7001d1d + 131832a commit 465a96c

25 files changed

+1112
-4
lines changed
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
name: Test Automation MACAE
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- dev
8+
paths:
9+
- 'tests/e2e-test/**'
10+
schedule:
11+
- cron: '0 13 * * *' # Runs at 1 PM UTC
12+
workflow_dispatch:
13+
14+
env:
15+
url: ${{ vars.MACAE_WEB_URL }}
16+
api_url: ${{ vars.MACAE_API_URL }}
17+
accelerator_name: "MACAE"
18+
19+
jobs:
20+
test:
21+
22+
runs-on: ubuntu-latest
23+
steps:
24+
- name: Checkout repository
25+
uses: actions/checkout@v4
26+
27+
- name: Set up Python
28+
uses: actions/setup-python@v4
29+
with:
30+
python-version: '3.13'
31+
32+
- name: Azure CLI Login
33+
uses: azure/login@v2
34+
with:
35+
creds: '{"clientId":"${{ secrets.AZURE_CLIENT_ID }}","clientSecret":"${{ secrets.AZURE_CLIENT_SECRET }}","subscriptionId":"${{ secrets.AZURE_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.AZURE_TENANT_ID }}"}'
36+
37+
- name: Start Container App
38+
id: start-container-app
39+
uses: azure/cli@v2
40+
with:
41+
azcliversion: 'latest'
42+
inlineScript: |
43+
az rest -m post -u "/subscriptions/${{ secrets.AZURE_SUBSCRIPTION_ID }}/resourceGroups/${{ vars.MACAE_RG }}/providers/Microsoft.App/containerApps/${{ vars.MACAE_BACKEND_CONTAINER_NAME }}/start?api-version=2025-01-01"
44+
45+
- name: Install dependencies
46+
run: |
47+
python -m pip install --upgrade pip
48+
pip install -r tests/e2e-test/requirements.txt
49+
50+
- name: Ensure browsers are installed
51+
run: python -m playwright install --with-deps chromium
52+
53+
- name: Run tests(1)
54+
id: test1
55+
run: |
56+
xvfb-run pytest --headed --html=report/report.html --self-contained-html
57+
working-directory: tests/e2e-test
58+
continue-on-error: true
59+
60+
- name: Sleep for 30 seconds
61+
if: ${{ steps.test1.outcome == 'failure' }}
62+
run: sleep 30s
63+
shell: bash
64+
65+
- name: Run tests(2)
66+
id: test2
67+
if: ${{ steps.test1.outcome == 'failure' }}
68+
run: |
69+
xvfb-run pytest --headed --html=report/report.html --self-contained-html
70+
working-directory: tests/e2e-test
71+
continue-on-error: true
72+
73+
- name: Sleep for 60 seconds
74+
if: ${{ steps.test2.outcome == 'failure' }}
75+
run: sleep 60s
76+
shell: bash
77+
78+
- name: Run tests(3)
79+
id: test3
80+
if: ${{ steps.test2.outcome == 'failure' }}
81+
run: |
82+
xvfb-run pytest --headed --html=report/report.html --self-contained-html
83+
working-directory: tests/e2e-test
84+
85+
- name: Upload test report
86+
id: upload_report
87+
uses: actions/upload-artifact@v4
88+
if: ${{ !cancelled() }}
89+
with:
90+
name: test-report
91+
path: tests/e2e-test/report/*
92+
93+
- name: Send Notification
94+
if: always()
95+
run: |
96+
RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
97+
REPORT_URL=${{ steps.upload_report.outputs.artifact-url }}
98+
IS_SUCCESS=${{ steps.test1.outcome == 'success' || steps.test2.outcome == 'success' || steps.test3.outcome == 'success' }}
99+
# Construct the email body
100+
if [ "$IS_SUCCESS" = "true" ]; then
101+
EMAIL_BODY=$(cat <<EOF
102+
{
103+
"body": "<p>Dear Team,</p><p>We would like to inform you that the ${{ env.accelerator_name }} Test Automation process has completed successfully.</p><p><strong>Run URL:</strong> <a href=\"${RUN_URL}\">${RUN_URL}</a><br></p><p><strong>Test Report:</strong> <a href=\"${REPORT_URL}\">${REPORT_URL}</a></p><p>Best regards,<br>Your Automation Team</p>",
104+
"subject": "${{ env.accelerator_name }} Test Automation - Success"
105+
}
106+
EOF
107+
)
108+
else
109+
EMAIL_BODY=$(cat <<EOF
110+
{
111+
"body": "<p>Dear Team,</p><p>We would like to inform you that the ${{ env.accelerator_name }} Test Automation process has encountered an issue and has failed to complete successfully.</p><p><strong>Run URL:</strong> <a href=\"${RUN_URL}\">${RUN_URL}</a><br> ${OUTPUT}</p><p><strong>Test Report:</strong> <a href=\"${REPORT_URL}\">${REPORT_URL}</a></p><p>Please investigate the matter at your earliest convenience.</p><p>Best regards,<br>Your Automation Team</p>",
112+
"subject": "${{ env.accelerator_name }} Test Automation - Failure"
113+
}
114+
EOF
115+
)
116+
fi
117+
118+
# Send the notification
119+
curl -X POST "${{ secrets.EMAILNOTIFICATION_LOGICAPP_URL_TA }}" \
120+
-H "Content-Type: application/json" \
121+
-d "$EMAIL_BODY" || echo "Failed to send notification"
122+
123+
- name: Stop Container App
124+
if: always()
125+
uses: azure/cli@v2
126+
with:
127+
azcliversion: 'latest'
128+
inlineScript: |
129+
az rest -m post -u "/subscriptions/${{ secrets.AZURE_SUBSCRIPTION_ID }}/resourceGroups/${{ vars.MACAE_RG }}/providers/Microsoft.App/containerApps/${{ vars.MACAE_BACKEND_CONTAINER_NAME }}/stop?api-version=2025-01-01"
130+
az logout

azure.yaml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,20 @@
11
# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json
22
name: multi-agent-custom-automation-engine-solution-accelerator
33
metadata:
4-
4+
5+
hooks:
6+
preprovision:
7+
posix:
8+
shell: sh
9+
run: >
10+
chmod u+r+x ./infra/scripts/validate_model_deployment_quota.sh; chmod u+r+x ./infra/scripts/validate_model_quota.sh; ./infra/scripts/validate_model_deployment_quota.sh --subscription "$AZURE_SUBSCRIPTION_ID" --location "${AZURE_ENV_OPENAI_LOCATION:-swedencentral}" --models-parameter "aiModelDeployments"
11+
interactive: false
12+
continueOnError: false
13+
14+
windows:
15+
shell: pwsh
16+
run: >
17+
$location = if ($env:AZURE_ENV_OPENAI_LOCATION) { $env:AZURE_ENV_OPENAI_LOCATION } else { "swedencentral" };
18+
./infra/scripts/validate_model_deployment_quotas.ps1 -SubscriptionId $env:AZURE_SUBSCRIPTION_ID -Location $location -ModelsParameter "aiModelDeployments"
19+
interactive: false
20+
continueOnError: false

infra/main.parameters.json

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
{
2+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
3+
"contentVersion": "1.0.0.0",
4+
"parameters": {
5+
"aiModelDeployments": {
6+
"value": [
7+
{
8+
"name": "gpt",
9+
"model": {
10+
"name": "gpt-4o",
11+
"version": "2024-08-06",
12+
"format": "OpenAI"
13+
},
14+
"sku": {
15+
"name": "GlobalStandard",
16+
"capacity": 140
17+
}
18+
}
19+
]
20+
},
21+
"environmentName": {
22+
"value": "${AZURE_ENV_NAME}"
23+
},
24+
"location": {
25+
"value": "${AZURE_LOCATION}"
26+
},
27+
"backendExists": {
28+
"value": "${SERVICE_BACKEND_RESOURCE_EXISTS=false}"
29+
},
30+
"backendDefinition": {
31+
"value": {
32+
"settings": [
33+
{
34+
"name": "",
35+
"value": "${VAR}",
36+
"_comment_name": "The name of the environment variable when running in Azure. If empty, ignored.",
37+
"_comment_value": "The value to provide. This can be a fixed literal, or an expression like ${VAR} to use the value of 'VAR' from the current environment."
38+
},
39+
{
40+
"name": "",
41+
"value": "${VAR_S}",
42+
"secret": true,
43+
"_comment_name": "The name of the environment variable when running in Azure. If empty, ignored.",
44+
"_comment_value": "The value to provide. This can be a fixed literal, or an expression like ${VAR_S} to use the value of 'VAR_S' from the current environment."
45+
}
46+
]
47+
}
48+
},
49+
"frontendExists": {
50+
"value": "${SERVICE_FRONTEND_RESOURCE_EXISTS=false}"
51+
},
52+
"frontendDefinition": {
53+
"value": {
54+
"settings": [
55+
{
56+
"name": "",
57+
"value": "${VAR}",
58+
"_comment_name": "The name of the environment variable when running in Azure. If empty, ignored.",
59+
"_comment_value": "The value to provide. This can be a fixed literal, or an expression like ${VAR} to use the value of 'VAR' from the current environment."
60+
},
61+
{
62+
"name": "",
63+
"value": "${VAR_S}",
64+
"secret": true,
65+
"_comment_name": "The name of the environment variable when running in Azure. If empty, ignored.",
66+
"_comment_value": "The value to provide. This can be a fixed literal, or an expression like ${VAR_S} to use the value of 'VAR_S' from the current environment."
67+
}
68+
]
69+
}
70+
},
71+
"principalId": {
72+
"value": "${AZURE_PRINCIPAL_ID}"
73+
}
74+
}
75+
}

infra/scripts/quota_check_params.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ az account set --subscription "$AZURE_SUBSCRIPTION_ID"
9292
echo "🎯 Active Subscription: $(az account show --query '[name, id]' --output tsv)"
9393

9494
# Default Regions to check (Comma-separated, now configurable)
95-
DEFAULT_REGIONS="eastus,uksouth,eastus2,northcentralus,swedencentral,westus,westus2,southcentralus,canadacentral"
95+
DEFAULT_REGIONS="australiaeast,eastus2,francecentral,japaneast,norwayeast,swedencentral,uksouth,westus"
9696
IFS=',' read -r -a DEFAULT_REGION_ARRAY <<< "$DEFAULT_REGIONS"
9797

9898
# Read parameters (if any)
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#!/bin/bash
2+
3+
SUBSCRIPTION_ID=""
4+
LOCATION=""
5+
MODELS_PARAMETER=""
6+
7+
while [[ $# -gt 0 ]]; do
8+
case "$1" in
9+
--subscription)
10+
SUBSCRIPTION_ID="$2"
11+
shift 2
12+
;;
13+
--location)
14+
LOCATION="$2"
15+
shift 2
16+
;;
17+
--models-parameter)
18+
MODELS_PARAMETER="$2"
19+
shift 2
20+
;;
21+
*)
22+
echo "Unknown option: $1"
23+
exit 1
24+
;;
25+
esac
26+
done
27+
28+
# Verify all required parameters are provided and echo missing ones
29+
MISSING_PARAMS=()
30+
31+
if [[ -z "$SUBSCRIPTION_ID" ]]; then
32+
MISSING_PARAMS+=("subscription")
33+
fi
34+
35+
if [[ -z "$LOCATION" ]]; then
36+
MISSING_PARAMS+=("location")
37+
fi
38+
39+
if [[ -z "$MODELS_PARAMETER" ]]; then
40+
MISSING_PARAMS+=("models-parameter")
41+
fi
42+
43+
if [[ ${#MISSING_PARAMS[@]} -ne 0 ]]; then
44+
echo "❌ ERROR: Missing required parameters: ${MISSING_PARAMS[*]}"
45+
echo "Usage: $0 --subscription <SUBSCRIPTION_ID> --location <LOCATION> --models-parameter <MODELS_PARAMETER>"
46+
exit 1
47+
fi
48+
49+
aiModelDeployments=$(jq -c ".parameters.$MODELS_PARAMETER.value[]" ./infra/main.parameters.json)
50+
51+
if [ $? -ne 0 ]; then
52+
echo "Error: Failed to parse main.parameters.json. Ensure jq is installed and the JSON file is valid."
53+
exit 1
54+
fi
55+
56+
az account set --subscription "$SUBSCRIPTION_ID"
57+
echo "🎯 Active Subscription: $(az account show --query '[name, id]' --output tsv)"
58+
59+
quotaAvailable=true
60+
61+
while IFS= read -r deployment; do
62+
name=$(echo "$deployment" | jq -r '.name')
63+
model=$(echo "$deployment" | jq -r '.model.name')
64+
type=$(echo "$deployment" | jq -r '.sku.name')
65+
capacity=$(echo "$deployment" | jq -r '.sku.capacity')
66+
67+
echo "🔍 Validating model deployment: $name ..."
68+
./infra/scripts/validate_model_quota.sh --location "$LOCATION" --model "$model" --capacity $capacity --deployment-type $type
69+
70+
# Check if the script failed
71+
exit_code=$?
72+
if [ $exit_code -ne 0 ]; then
73+
if [ $exit_code -eq 2 ]; then
74+
# Skip printing any quota validation error — already handled inside the validation script
75+
exit 1
76+
fi
77+
echo "❌ ERROR: Quota validation failed for model deployment: $name"
78+
quotaAvailable=false
79+
fi
80+
done <<< "$(echo "$aiModelDeployments")"
81+
82+
if [ "$quotaAvailable" = false ]; then
83+
echo "❌ ERROR: One or more model deployments failed validation."
84+
exit 1
85+
else
86+
echo "✅ All model deployments passed quota validation successfully."
87+
exit 0
88+
fi

0 commit comments

Comments
 (0)