Skip to content

Commit 4fc4350

Browse files
Merge pull request #394 from microsoft/dev
feat: EXP Changes to reuse the existing resource and added Automation tests
2 parents 6009704 + a1c6131 commit 4fc4350

File tree

19 files changed

+1145
-266
lines changed

19 files changed

+1145
-266
lines changed

.github/workflows/CI.yml

Lines changed: 219 additions & 212 deletions
Large diffs are not rendered by default.
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
name: Test Automation DKM
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.DKM_URL }}
16+
accelerator_name: "DKM"
17+
18+
jobs:
19+
test:
20+
runs-on: ubuntu-latest
21+
steps:
22+
- name: Checkout repository
23+
uses: actions/checkout@v4
24+
25+
- name: Set up Python
26+
uses: actions/setup-python@v4
27+
with:
28+
python-version: '3.13'
29+
30+
- name: Azure CLI Login
31+
uses: azure/login@v2
32+
with:
33+
creds: '{"clientId":"${{ secrets.AZURE_CLIENT_ID }}","clientSecret":"${{ secrets.AZURE_CLIENT_SECRET }}","subscriptionId":"${{ secrets.AZURE_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.AZURE_TENANT_ID }}"}'
34+
35+
- name: Start AKS
36+
id: start-aks
37+
uses: azure/cli@v2
38+
with:
39+
azcliversion: 'latest'
40+
inlineScript: |
41+
az aks install-cli
42+
if [ "$(az aks show --resource-group ${{ vars.DKM_RG }} --name ${{ vars.DKM_AKS_NAME }} --query "powerState.code" -o tsv)" = "Running" ]; then echo "AKS is running"; else az aks start --resource-group ${{ vars.DKM_RG }} --name ${{ vars.DKM_AKS_NAME }}; fi
43+
44+
- name: Install dependencies
45+
run: |
46+
python -m pip install --upgrade pip
47+
pip install -r tests/e2e-test/requirements.txt
48+
49+
- name: Ensure browsers are installed
50+
run: python -m playwright install --with-deps chromium
51+
52+
- name: Run tests(1)
53+
id: test1
54+
run: |
55+
xvfb-run pytest --headed --html=report/report.html --self-contained-html
56+
working-directory: tests/e2e-test
57+
continue-on-error: true
58+
59+
- name: Sleep for 30 seconds
60+
if: ${{ steps.test1.outcome == 'failure' }}
61+
run: sleep 30s
62+
shell: bash
63+
64+
- name: Run tests(2)
65+
id: test2
66+
if: ${{ steps.test1.outcome == 'failure' }}
67+
run: |
68+
xvfb-run pytest --headed --html=report/report.html --self-contained-html
69+
working-directory: tests/e2e-test
70+
continue-on-error: true
71+
72+
- name: Sleep for 60 seconds
73+
if: ${{ steps.test2.outcome == 'failure' }}
74+
run: sleep 60s
75+
shell: bash
76+
77+
- name: Run tests(3)
78+
id: test3
79+
if: ${{ steps.test2.outcome == 'failure' }}
80+
run: |
81+
xvfb-run pytest --headed --html=report/report.html --self-contained-html
82+
working-directory: tests/e2e-test
83+
84+
- name: Upload test report
85+
id: upload_report
86+
uses: actions/upload-artifact@v4
87+
if: ${{ !cancelled() }}
88+
with:
89+
name: test-report
90+
path: tests/e2e-test/report/*
91+
92+
- name: Send Notification
93+
if: always()
94+
run: |
95+
RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
96+
REPORT_URL=${{ steps.upload_report.outputs.artifact-url }}
97+
IS_SUCCESS=${{ steps.test1.outcome == 'success' || steps.test2.outcome == 'success' || steps.test3.outcome == 'success' }}
98+
# Construct the email body
99+
if [ "$IS_SUCCESS" = "true" ]; then
100+
EMAIL_BODY=$(cat <<EOF
101+
{
102+
"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>",
103+
"subject": "${{ env.accelerator_name }} Test Automation - Success"
104+
}
105+
EOF
106+
)
107+
else
108+
EMAIL_BODY=$(cat <<EOF
109+
{
110+
"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></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>",
111+
"subject": "${{ env.accelerator_name }} Test Automation - Failure"
112+
}
113+
EOF
114+
)
115+
fi
116+
117+
# Send the notification
118+
curl -X POST "${{ secrets.EMAILNOTIFICATION_LOGICAPP_URL_TA }}" \
119+
-H "Content-Type: application/json" \
120+
-d "$EMAIL_BODY" || echo "Failed to send notification"
121+
122+
- name: Stop AKS
123+
if: always()
124+
uses: azure/cli@v2
125+
with:
126+
azcliversion: 'latest'
127+
inlineScript: |
128+
az aks install-cli
129+
if [ "$(az aks show --resource-group ${{ vars.DKM_RG }} --name ${{ vars.DKM_AKS_NAME }} --query "powerState.code" -o tsv)" = "Running" ]; then az aks stop --resource-group ${{ vars.DKM_RG }} --name ${{ vars.DKM_AKS_NAME }}; else echo "AKS is already stopped"; fi
130+
az logout

Deployment/main.bicep

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,67 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT license.
3+
4+
targetScope = 'resourceGroup'
5+
6+
@minLength(3)
7+
@maxLength(20)
8+
@description('A unique prefix for all resources in this deployment. This should be 3-20 characters long:')
9+
param environmentName string
10+
311
@description('The Data Center where the model is deployed.')
412
param modeldatacenter string
5-
var abbrs = loadJsonContent('./abbreviations.json')
613

7-
targetScope = 'subscription'
8-
var resourceprefix = padLeft(take(uniqueString(deployment().name), 5), 5, '0')
14+
@description('Azure data center region where resources will be deployed. This should be a valid Azure region, e.g., eastus, westus, etc.')
15+
param location string
16+
17+
var uniqueId = toLower(uniqueString(subscription().id, environmentName, location))
18+
var resourceprefix = padLeft(take(uniqueId, 10), 10, '0')
919
var resourceprefix_name = 'kmgs'
1020

11-
// Create a resource group
12-
resource gs_resourcegroup 'Microsoft.Resources/resourceGroups@2021-04-01' = {
13-
name: '${abbrs.managementGovernance.resourceGroup}${resourceprefix_name}${resourceprefix}'
14-
location: deployment().location
15-
}
21+
var resourceGroupLocation = resourceGroup().location
22+
23+
// Load the abbrevations file required to name the azure resources.
24+
var abbrs = loadJsonContent('./abbreviations.json')
25+
1626

1727
// Create a storage account
1828
module gs_storageaccount 'bicep/azurestorageaccount.bicep' = {
1929
name: '${abbrs.storage.storageAccount}${resourceprefix_name}${resourceprefix}'
20-
scope: gs_resourcegroup
30+
scope: resourceGroup()
2131
params: {
2232
storageAccountName: '${abbrs.storage.storageAccount}${resourceprefix}'
23-
location: deployment().location
33+
location: resourceGroupLocation
2434
}
2535
}
2636

2737
// Create a Azure Search Service
2838
module gs_azsearch 'bicep/azuresearch.bicep' = {
2939
name: '${abbrs.ai.aiSearch}${resourceprefix_name}${resourceprefix}'
30-
scope: gs_resourcegroup
40+
scope: resourceGroup()
3141
params: {
3242
searchServiceName: '${abbrs.ai.aiSearch}${resourceprefix}'
33-
location: deployment().location
43+
location: resourceGroupLocation
3444
}
3545
}
3646

3747

3848
// Create Container Registry
3949
module gs_containerregistry 'bicep/azurecontainerregistry.bicep' = {
4050
name: '${abbrs.containers.containerRegistry}${resourceprefix_name}${resourceprefix}'
41-
scope: gs_resourcegroup
51+
scope: resourceGroup()
4252
params: {
4353
acrName: '${abbrs.containers.containerRegistry}${resourceprefix_name}${resourceprefix}'
44-
location: deployment().location
54+
location: resourceGroupLocation
4555
}
4656
}
4757

4858
// Create AKS Cluster
4959
module gs_aks 'bicep/azurekubernetesservice.bicep' = {
5060
name: '${abbrs.compute.arcEnabledKubernetesCluster}${resourceprefix_name}${resourceprefix}'
51-
scope: gs_resourcegroup
61+
scope: resourceGroup()
5262
params: {
5363
aksName: '${abbrs.compute.arcEnabledKubernetesCluster}${resourceprefix_name}${resourceprefix}'
54-
location: deployment().location
64+
location: resourceGroupLocation
5565
}
5666
dependsOn: [
5767
gs_containerregistry
@@ -76,7 +86,7 @@ module gs_aks 'bicep/azurekubernetesservice.bicep' = {
7686
// Create Azure Cognitive Service
7787
module gs_azcognitiveservice 'bicep/azurecognitiveservice.bicep' = {
7888
name: '${abbrs.ai.documentIntelligence}${resourceprefix_name}${resourceprefix}'
79-
scope: gs_resourcegroup
89+
scope: resourceGroup()
8090
params: {
8191
cognitiveServiceName: '${abbrs.ai.documentIntelligence}${resourceprefix_name}${resourceprefix}'
8292
location: 'eastus'
@@ -86,7 +96,7 @@ module gs_azcognitiveservice 'bicep/azurecognitiveservice.bicep' = {
8696
// Create Azure Open AI Service
8797
module gs_openaiservice 'bicep/azureopenaiservice.bicep' = {
8898
name: '${abbrs.ai.openAIService}${resourceprefix_name}${resourceprefix}'
89-
scope: gs_resourcegroup
99+
scope: resourceGroup()
90100
params: {
91101
openAIServiceName: '${abbrs.ai.openAIService}${resourceprefix_name}${resourceprefix}'
92102
// GPT-4-32K model & GPT-4o available Data center information.
@@ -99,7 +109,7 @@ module gs_openaiservice 'bicep/azureopenaiservice.bicep' = {
99109
// Set the minimum capacity of each model
100110
// Based on customer's Model capacity, it needs to be updated in Azure Portal.
101111
module gs_openaiservicemodels_gpt4o 'bicep/azureopenaiservicemodel.bicep' = {
102-
scope: gs_resourcegroup
112+
scope: resourceGroup()
103113
name: 'gpt-4o-mini'
104114
params: {
105115
parentResourceName: gs_openaiservice.outputs.openAIServiceName
@@ -119,7 +129,7 @@ module gs_openaiservicemodels_gpt4o 'bicep/azureopenaiservicemodel.bicep' = {
119129
}
120130

121131
module gs_openaiservicemodels_text_embedding 'bicep/azureopenaiservicemodel.bicep' = {
122-
scope: gs_resourcegroup
132+
scope: resourceGroup()
123133
name: 'text-embedding-large'
124134
params: {
125135
parentResourceName: gs_openaiservice.outputs.openAIServiceName
@@ -140,25 +150,26 @@ module gs_openaiservicemodels_text_embedding 'bicep/azureopenaiservicemodel.bice
140150
// Create Azure Cosmos DB Mongo
141151
module gs_cosmosdb 'bicep/azurecosmosdb.bicep' = {
142152
name: '${abbrs.databases.cosmosDBDatabase}${resourceprefix_name}${resourceprefix}'
143-
scope: gs_resourcegroup
153+
scope: resourceGroup()
144154
params: {
145155
cosmosDbAccountName: '${abbrs.databases.cosmosDBDatabase}${resourceprefix_name}${resourceprefix}'
146-
location: deployment().location
156+
location: resourceGroupLocation
147157
}
148158
}
149159

150160
// Create Azure App Configuration
151161
module gs_appconfig 'bicep/azureappconfigservice.bicep' = {
152162
name: 'appconfig-${resourceprefix_name}${resourceprefix}'
153-
scope: gs_resourcegroup
163+
scope: resourceGroup()
154164
params: {
155165
appConfigName: 'appconfig-${resourceprefix_name}${resourceprefix}'
156-
location: deployment().location
166+
location: resourceGroupLocation
157167
}
158168
}
159169

160170
// return all resource names as a output
161-
output gs_resourcegroup_name string = '${abbrs.managementGovernance.resourceGroup}${resourceprefix_name}${resourceprefix}'
171+
// output gs_resourcegroup_name string = '${abbrs.managementGovernance.resourceGroup}${resourceprefix_name}${resourceprefix}'
172+
output gs_resourcegroup_name string = resourceGroup().name
162173
output gs_solution_prefix string = '${resourceprefix_name}${resourceprefix}'
163174
output gs_storageaccount_name string = gs_storageaccount.outputs.storageAccountName
164175
output gs_azsearch_name string = gs_azsearch.outputs.searchServiceName
@@ -189,5 +200,5 @@ output gs_appconfig_endpoint string = gs_appconfig.outputs.appConfigEndpoint
189200
output gs_containerregistry_endpoint string = gs_containerregistry.outputs.acrEndpoint
190201

191202
//return resourcegroup resource ID
192-
output gs_resourcegroup_id string = gs_resourcegroup.id
203+
output gs_resourcegroup_id string = resourceGroup().id
193204

Deployment/resourcePrefix.bicep

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
targetScope = 'subscription'
2+
3+
param environmentName string
4+
param location string
5+
6+
var uniqueId = toLower(uniqueString(subscription().id, environmentName, location))
7+
var resourceprefix = padLeft(take(uniqueId, 10), 10, '0')
8+
9+
output resourcePrefix string = resourceprefix

0 commit comments

Comments
 (0)