Skip to content

Commit 45bf40f

Browse files
author
Harmanpreet Kaur
committed
Merge remote-tracking branch 'origin/dev' into dependabotchanges
2 parents 518d425 + 234b18b commit 45bf40f

File tree

78 files changed

+55069
-3541
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+55069
-3541
lines changed

.github/workflows/CI.yml

Lines changed: 155 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ on:
99
- cron: "0 10,22 * * *" # Runs at 10:00 AM and 10:00 PM GMT
1010

1111
env:
12-
GPT_CAPACITY: 250
12+
GPT_CAPACITY: 150
1313
TEXT_EMBEDDING_CAPACITY: 200
1414

1515
jobs:
@@ -42,11 +42,32 @@ jobs:
4242
- name: Install Helm
4343
shell: bash
4444
run: |
45-
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
46-
sudo apt-get install apt-transport-https --yes
45+
# If helm is already available on the runner, print version and skip installation
46+
if command -v helm >/dev/null 2>&1; then
47+
echo "helm already installed: $(helm version --short 2>/dev/null || true)"
48+
exit 0
49+
fi
50+
51+
# Ensure prerequisites are present
52+
sudo apt-get update
53+
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release
54+
55+
# Ensure keyrings dir exists
56+
sudo mkdir -p /usr/share/keyrings
57+
58+
# Add Helm GPG key (use -fS to fail fast on curl errors)
59+
curl -fsSL https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg >/dev/null
60+
61+
# Add the Helm apt repository
4762
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
63+
64+
# Install helm
4865
sudo apt-get update
49-
sudo apt-get install helm
66+
sudo apt-get install -y helm
67+
68+
# Verify
69+
echo "Installed helm version:"
70+
helm version
5071
5172
- name: Set up Docker
5273
uses: docker/setup-buildx-action@v3
@@ -112,48 +133,159 @@ jobs:
112133
if: env.QUOTA_FAILED == 'true'
113134
run: exit 1
114135

115-
- name: Generate Environment Name
116-
id: generate_environment_name
136+
- name: Install Bicep CLI
137+
run: az bicep install
138+
139+
- name: Install Azure Developer CLI
140+
run: |
141+
curl -fsSL https://aka.ms/install-azd.sh | bash
117142
shell: bash
143+
144+
- name: Set Deployment Region
145+
run: |
146+
echo "Selected Region: $VALID_REGION"
147+
echo "AZURE_LOCATION=$VALID_REGION" >> $GITHUB_ENV
148+
149+
- name: Generate Resource Group Name
150+
id: generate_rg_name
151+
run: |
152+
echo "Generating a unique resource group name..."
153+
ACCL_NAME="dkm" # Account name as specified
154+
SHORT_UUID=$(uuidgen | cut -d'-' -f1)
155+
UNIQUE_RG_NAME="arg-${ACCL_NAME}-${SHORT_UUID}"
156+
echo "RESOURCE_GROUP_NAME=${UNIQUE_RG_NAME}" >> $GITHUB_ENV
157+
echo "Generated RESOURCE_GROUP_NAME: ${UNIQUE_RG_NAME}"
158+
159+
- name: Login to Azure
160+
run: |
161+
az login --service-principal -u ${{ secrets.AZURE_CLIENT_ID }} -p ${{ secrets.AZURE_CLIENT_SECRET }} --tenant ${{ secrets.AZURE_TENANT_ID }}
162+
az account set --subscription ${{ secrets.AZURE_SUBSCRIPTION_ID }}
163+
164+
- name: Check and Create Resource Group
165+
id: check_create_rg
166+
run: |
167+
set -e
168+
echo "Checking if resource group exists..."
169+
rg_exists=$(az group exists --name ${{ env.RESOURCE_GROUP_NAME }})
170+
if [ "$rg_exists" = "false" ]; then
171+
echo "Resource group does not exist. Creating..."
172+
az group create --name ${{ env.RESOURCE_GROUP_NAME }} --location ${{ env.AZURE_LOCATION }} || { echo "Error creating resource group"; exit 1; }
173+
else
174+
echo "Resource group already exists."
175+
fi
176+
echo "RESOURCE_GROUP_NAME=${{ env.RESOURCE_GROUP_NAME }}" >> $GITHUB_OUTPUT
177+
178+
- name: Generate Unique Solution Prefix
179+
id: generate_solution_prefix
180+
run: |
181+
set -e
182+
COMMON_PART="psldkm"
183+
TIMESTAMP=$(date +%s)
184+
UPDATED_TIMESTAMP=$(echo $TIMESTAMP | tail -c 6)
185+
UNIQUE_SOLUTION_PREFIX="${COMMON_PART}${UPDATED_TIMESTAMP}"
186+
echo "SOLUTION_PREFIX=${UNIQUE_SOLUTION_PREFIX}" >> $GITHUB_ENV
187+
echo "Generated SOLUTION_PREFIX: ${UNIQUE_SOLUTION_PREFIX}"
188+
189+
- name: Deploy Bicep Template
190+
id: deploy
118191
run: |
119192
set -e
120-
TIMESTAMP_SHORT=$(date +%s | tail -c 5) # Last 4-5 digits of epoch seconds
121-
RANDOM_SUFFIX=$(head /dev/urandom | tr -dc 'a-z0-9' | head -c 8) # 8 random alphanum chars
122-
UNIQUE_ENV_NAME="${TIMESTAMP_SHORT}${RANDOM_SUFFIX}" # Usually ~12-13 chars
123-
echo "ENVIRONMENT_NAME=${UNIQUE_ENV_NAME}" >> $GITHUB_ENV
124-
echo "Generated ENVIRONMENT_NAME: ${UNIQUE_ENV_NAME}"
193+
194+
# Generate current timestamp in desired format: YYYY-MM-DDTHH:MM:SS.SSSSSSSZ
195+
current_date=$(date -u +"%Y-%m-%dT%H:%M:%S.%7NZ")
196+
197+
az deployment group create \
198+
--name ${{ env.SOLUTION_PREFIX }}-deployment \
199+
--resource-group ${{ env.RESOURCE_GROUP_NAME }} \
200+
--template-file infra/main.bicep \
201+
--parameters \
202+
solutionName="${{ env.SOLUTION_PREFIX }}" \
203+
location=${{ env.AZURE_LOCATION }} \
204+
aiDeploymentsLocation=${{ env.AZURE_LOCATION }} \
205+
gptModelDeploymentType="GlobalStandard" \
206+
gptModelName="gpt-4.1-mini" \
207+
gptModelCapacity=${{ env.GPT_CAPACITY }} \
208+
gptModelVersion="2025-04-14" \
209+
embeddingModelName="text-embedding-3-large" \
210+
embeddingModelCapacity=${{ env.TEXT_EMBEDDING_CAPACITY }} \
211+
embeddingModelVersion="1" \
212+
enablePrivateNetworking=false \
213+
enableMonitoring=false \
214+
enableTelemetry=true \
215+
enableRedundancy=false \
216+
enableScalability=false \
217+
createdBy="Pipeline" \
218+
tags="{'SecurityControl':'Ignore','Purpose':'Deploying and Cleaning Up Resources for Validation','CreatedDate':'$current_date'}"
219+
220+
- name: Get Deployment Output and extract Values
221+
id: get_output
222+
run: |
223+
set -e
224+
echo "Fetching deployment output..."
225+
BICEP_OUTPUT=$(az deployment group show \
226+
--name ${{ env.SOLUTION_PREFIX }}-deployment \
227+
--resource-group ${{ env.RESOURCE_GROUP_NAME }} \
228+
--query "properties.outputs" -o json)
229+
230+
echo "Deployment outputs:"
231+
echo "$BICEP_OUTPUT"
232+
233+
# Write outputs to GitHub env
234+
# Loop through keys, normalize to uppercase, and export
235+
for key in $(echo "$BICEP_OUTPUT" | jq -r 'keys[]'); do
236+
value=$(echo "$BICEP_OUTPUT" | jq -r ".[\"$key\"].value")
237+
upper_key=$(echo "$key" | tr '[:lower:]' '[:upper:]')
238+
echo "$upper_key=$value" >> $GITHUB_ENV
239+
done
125240
126241
- name: Run Deployment Script with Input
127242
shell: pwsh
128243
run: |
129244
cd Deployment
130245
$input = @"
131-
${{ secrets.AZURE_TENANT_ID }}
132-
${{ secrets.AZURE_SUBSCRIPTION_ID }}
133-
${{ env.ENVIRONMENT_NAME }}
134-
135-
CanadaCentral
136-
${{ env.VALID_REGION }}
137246
${{ secrets.EMAIL }}
138247
yes
139248
"@
140249
$input | pwsh ./resourcedeployment.ps1
141-
Write-Host "Resource Group Name is ${{ env.rg_name }}"
142-
Write-Host "Kubernetes resource group are ${{ env.krg_name }}"
250+
Write-Host "Resource Group Name is ${{ env.RESOURCE_GROUP_NAME }}"
251+
Write-Host "Kubernetes resource group is ${{ env.AZURE_AKS_NAME }}"
143252
env:
253+
# From GitHub secrets (for login)
144254
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
145-
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
146-
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
147-
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
255+
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
256+
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
257+
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
258+
259+
# From deployment outputs step (these come from $GITHUB_ENV)
260+
RESOURCE_GROUP_NAME: ${{ env.RESOURCE_GROUP_NAME }}
261+
AZURE_RESOURCE_GROUP_ID: ${{ env.AZURE_RESOURCE_GROUP_ID }}
262+
STORAGE_ACCOUNT_NAME: ${{ env.STORAGE_ACCOUNT_NAME }}
263+
AZURE_SEARCH_SERVICE_NAME: ${{ env.AZURE_SEARCH_SERVICE_NAME }}
264+
AZURE_AKS_NAME: ${{ env.AZURE_AKS_NAME }}
265+
AZURE_AKS_MI_ID: ${{ env.AZURE_AKS_MI_ID }}
266+
AZURE_CONTAINER_REGISTRY_NAME: ${{ env.AZURE_CONTAINER_REGISTRY_NAME }}
267+
AZURE_COGNITIVE_SERVICE_NAME: ${{ env.AZURE_COGNITIVE_SERVICE_NAME }}
268+
AZURE_COGNITIVE_SERVICE_ENDPOINT: ${{ env.AZURE_COGNITIVE_SERVICE_ENDPOINT }}
269+
AZURE_OPENAI_SERVICE_NAME: ${{ env.AZURE_OPENAI_SERVICE_NAME }}
270+
AZURE_OPENAI_SERVICE_ENDPOINT: ${{ env.AZURE_OPENAI_SERVICE_ENDPOINT }}
271+
AZURE_COSMOSDB_NAME: ${{ env.AZURE_COSMOSDB_NAME }}
272+
AZ_GPT4O_MODEL_NAME: ${{ env.AZ_GPT4O_MODEL_NAME }}
273+
AZ_GPT4O_MODEL_ID: ${{ env.AZ_GPT4O_MODEL_ID }}
274+
AZ_GPT_EMBEDDING_MODEL_NAME: ${{ env.AZ_GPT_EMBEDDING_MODEL_NAME }}
275+
AZ_GPT_EMBEDDING_MODEL_ID: ${{ env.AZ_GPT_EMBEDDING_MODEL_ID }}
276+
AZURE_APP_CONFIG_ENDPOINT: ${{ env.AZURE_APP_CONFIG_ENDPOINT }}
277+
AZURE_APP_CONFIG_NAME: ${{ env.AZURE_APP_CONFIG_NAME }}
148278

149279
- name: Extract Web App URL and Increase TPM
150280
id: get_webapp_url
151281
shell: bash
152282
run: |
153283
# Save the resource group name and Kubernetes resource group name to GITHUB_OUTPUT
154-
echo "RESOURCE_GROUP_NAME=${{ env.rg_name }}" >> $GITHUB_OUTPUT
284+
echo "RESOURCE_GROUP_NAME=${{ env.RESOURCE_GROUP_NAME }}" >> $GITHUB_OUTPUT
155285
echo "KUBERNETES_RESOURCE_GROUP_NAME=${{ env.krg_name }}" >> $GITHUB_OUTPUT
156286
echo "VALID_REGION=${{ env.VALID_REGION }}" >> $GITHUB_OUTPUT
287+
echo "OPENAI_RESOURCE_NAME=${{ env.AZURE_OPENAI_SERVICE_NAME }}" >> $GITHUB_OUTPUT
288+
echo "DOCUMENT_INTELLIGENCE_RESOURCE_NAME=${{ env.AZURE_COGNITIVE_SERVICE_NAME }}" >> $GITHUB_OUTPUT
157289
158290
if az account show &> /dev/null; then
159291
echo "Azure CLI is authenticated."
@@ -175,43 +307,6 @@ jobs:
175307
exit 1
176308
fi
177309
178-
# Get Azure OpenAI resource name
179-
openai_resource_name=$(az cognitiveservices account list --resource-group ${{ env.rg_name }} --query "[?kind=='OpenAI'].name | [0]" -o tsv)
180-
if [ -z "$openai_resource_name" ]; then
181-
echo "No Azure OpenAI resource found in the resource group."
182-
exit 1
183-
fi
184-
echo "OpenAI resource name is $openai_resource_name"
185-
echo "OPENAI_RESOURCE_NAME=$openai_resource_name" >> $GITHUB_OUTPUT
186-
187-
# Get Azure Document Intelligence resource name
188-
document_intelligence_resource_name=$(az cognitiveservices account list --resource-group ${{ env.rg_name }} --query "[?kind=='FormRecognizer'].name | [0]" -o tsv)
189-
if [ -z "$document_intelligence_resource_name" ]; then
190-
echo "No Azure Document Intelligence resource found in the resource group."
191-
else
192-
echo "Document Intelligence resource name is $document_intelligence_resource_name"
193-
echo "DOCUMENT_INTELLIGENCE_RESOURCE_NAME=$document_intelligence_resource_name" >> $GITHUB_OUTPUT
194-
fi
195-
196-
# Increase the TPM for the Azure OpenAI models
197-
echo "Increasing TPM for Azure OpenAI models..."
198-
openai_gpt_deployment_url="/subscriptions/${{ secrets.AZURE_SUBSCRIPTION_ID }}/resourceGroups/${{ env.rg_name }}/providers/Microsoft.CognitiveServices/accounts/$openai_resource_name/deployments/gpt-4o-mini?api-version=2023-05-01"
199-
az rest -m put -u "$openai_gpt_deployment_url" -b "{'sku':{'name':'Standard','capacity':${{ env.GPT_CAPACITY }}},'properties': {'model': {'format': 'OpenAI','name': 'gpt-4o-mini','version': '2024-07-18'}}}"
200-
if [ $? -ne 0 ]; then
201-
echo "Failed to increase TPM for GPT deployment."
202-
exit 1
203-
else
204-
echo "Successfully increased TPM for GPT deployment."
205-
fi
206-
openai_embedding_deployment_url="/subscriptions/${{ secrets.AZURE_SUBSCRIPTION_ID }}/resourceGroups/${{ env.rg_name }}/providers/Microsoft.CognitiveServices/accounts/$openai_resource_name/deployments/text-embedding-large?api-version=2023-05-01"
207-
az rest -m put -u "$openai_embedding_deployment_url" -b "{'sku':{'name':'Standard','capacity': ${{ env.TEXT_EMBEDDING_CAPACITY }}},'properties': {'model': {'format': 'OpenAI','name': 'text-embedding-3-large','version': '1'}}}"
208-
if [ $? -ne 0 ]; then
209-
echo "Failed to increase TPM for Text Embedding deployment."
210-
exit 1
211-
else
212-
echo "Successfully increased TPM for Text Embedding deployment."
213-
fi
214-
215310
- name: Validate Deployment
216311
shell: bash
217312
run: |
@@ -283,7 +378,6 @@ jobs:
283378
echo "Azure CLI is not authenticated. Skipping logout."
284379
fi
285380
286-
287381
e2e-test:
288382
needs: deploy
289383
uses: ./.github/workflows/test-automation.yml
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
on:
2+
push:
3+
branches:
4+
- main
5+
6+
permissions:
7+
contents: write
8+
pull-requests: write
9+
10+
name: Create-Release
11+
12+
jobs:
13+
create-release:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v4
18+
with:
19+
ref: ${{ github.event.workflow_run.head_sha }}
20+
21+
- uses: codfish/semantic-release-action@v3
22+
id: semantic
23+
with:
24+
tag-format: 'v${version}'
25+
additional-packages: |
26+
['conventional-changelog-conventionalcommits@7']
27+
plugins: |
28+
[
29+
[
30+
"@semantic-release/commit-analyzer",
31+
{
32+
"preset": "conventionalcommits"
33+
}
34+
],
35+
[
36+
"@semantic-release/release-notes-generator",
37+
{
38+
"preset": "conventionalcommits",
39+
"presetConfig": {
40+
"types": [
41+
{ type: 'feat', section: 'Features', hidden: false },
42+
{ type: 'fix', section: 'Bug Fixes', hidden: false },
43+
{ type: 'perf', section: 'Performance Improvements', hidden: false },
44+
{ type: 'revert', section: 'Reverts', hidden: false },
45+
{ type: 'docs', section: 'Other Updates', hidden: false },
46+
{ type: 'style', section: 'Other Updates', hidden: false },
47+
{ type: 'chore', section: 'Other Updates', hidden: false },
48+
{ type: 'refactor', section: 'Other Updates', hidden: false },
49+
{ type: 'test', section: 'Other Updates', hidden: false },
50+
{ type: 'build', section: 'Other Updates', hidden: false },
51+
{ type: 'ci', section: 'Other Updates', hidden: false }
52+
]
53+
}
54+
}
55+
],
56+
'@semantic-release/github'
57+
]
58+
env:
59+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
60+
- run: echo ${{ steps.semantic.outputs.release-version }}
61+
62+
- run: echo "$OUTPUTS"
63+
env:
64+
OUTPUTS: ${{ toJson(steps.semantic.outputs) }}
65+

App/backend-api/Microsoft.GS.DPS.Host/AppConfiguration/AppConfiguration.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Azure.Identity;
22
using Microsoft.Extensions.Azure;
33
using Microsoft.GS.DPSHost.AppConfiguration;
4+
using Microsoft.GS.DPSHost.Helpers;
45

56
namespace Microsoft.GS.DPSHost.AppConfiguration
67
{
@@ -16,7 +17,7 @@ public static void Config(IHostApplicationBuilder builder)
1617
//Read AppConfiguration with managed Identity
1718
builder.Configuration.AddAzureAppConfiguration(options =>
1819
{
19-
options.Connect(new Uri(builder.Configuration["ConnectionStrings:AppConfig"]), new DefaultAzureCredential());
20+
options.Connect(new Uri(builder.Configuration["ConnectionStrings:AppConfig"]), AzureCredentialHelper.GetAzureCredential());
2021
});
2122

2223
//Read ServiceConfiguration

App/backend-api/Microsoft.GS.DPS.Host/DependencyConfiguration/ServiceDependencies.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using Microsoft.GS.DPS.Storage.AISearch;
1313
using Microsoft.GS.DPSHost.AppConfiguration;
1414
using Microsoft.Extensions.DependencyInjection;
15+
using Microsoft.GS.DPSHost.Helpers;
1516

1617
namespace Microsoft.GS.DPSHost.ServiceConfiguration
1718
{
@@ -31,7 +32,7 @@ public static void Inject(IHostApplicationBuilder builder)
3132
return Kernel.CreateBuilder()
3233
.AddAzureOpenAIChatCompletion(deploymentName: builder.Configuration.GetSection("Application:AIServices:GPT-4o-mini")["ModelName"] ?? "",
3334
endpoint: builder.Configuration.GetSection("Application:AIServices:GPT-4o-mini")["Endpoint"] ?? "",
34-
apiKey: builder.Configuration.GetSection("Application:AIServices:GPT-4o-mini")["Key"] ?? "")
35+
credentials: AzureCredentialHelper.GetAzureCredential())
3536

3637
.Build();
3738
})
@@ -66,7 +67,7 @@ public static void Inject(IHostApplicationBuilder builder)
6667
.AddSingleton<TagUpdater>(x =>
6768
{
6869
var services = x.GetRequiredService<IOptions<Services>>().Value;
69-
return new TagUpdater(services.AzureAISearch.Endpoint, services.AzureAISearch.APIKey);
70+
return new TagUpdater(services.AzureAISearch.Endpoint, AzureCredentialHelper.GetAzureCredential());
7071

7172
})
7273

0 commit comments

Comments
 (0)