Skip to content

Commit fa1ac12

Browse files
Merge pull request #688 from microsoft/main
chore: merging to demo from main
2 parents f439439 + a16a821 commit fa1ac12

458 files changed

Lines changed: 71793 additions & 4543 deletions

File tree

Some content is hidden

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

.devcontainer/Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
FROM mcr.microsoft.com/devcontainers/python:3.11-bullseye
2+
3+
# Remove Yarn repository to avoid GPG key expiration issue
4+
RUN rm -f /etc/apt/sources.list.d/yarn.list

.devcontainer/devcontainer.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
{
22
"name": "azd-template",
3-
"image": "mcr.microsoft.com/devcontainers/python:3.11-bullseye",
4-
"forwardPorts": [50505],
3+
"build": {
4+
"dockerfile": "Dockerfile"
5+
},
6+
"forwardPorts": [3000, 5000],
57
"features": {
68
"ghcr.io/devcontainers/features/node:1": {
79
"nodeGypDependencies": true,

.devcontainer/setup_env.sh

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,3 @@
22

33
git fetch
44
git pull
5-
6-
# provide execute permission to quotacheck script
7-
sudo chmod +x ./scripts/quota_check_params.sh

.github/workflows/azure-dev.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: Azure Template Validation
22
on:
3-
workflow_dispatch:
3+
workflow_dispatch:
44

55
permissions:
66
contents: read
@@ -15,20 +15,21 @@ jobs:
1515
steps:
1616
# Step 1: Checkout the code from your repository
1717
- name: Checkout code
18-
uses: actions/checkout@v5
18+
uses: actions/checkout@v4
1919

2020
# Step 2: Validate the Azure template using microsoft/template-validation-action
2121
- name: Validate Azure Template
2222
uses: microsoft/template-validation-action@v0.4.3
2323
id: validation
24+
with:
25+
workingDirectory: ./content-gen
2426
env:
2527
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
2628
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
2729
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
2830
AZURE_ENV_NAME: ${{ secrets.AZURE_ENV_NAME }}
2931
AZURE_LOCATION: ${{ secrets.AZURE_LOCATION }}
3032
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
31-
AZURE_DEV_COLLECT_TELEMETRY: ${{ vars.AZURE_DEV_COLLECT_TELEMETRY }}
3233

3334
# Step 3: Print the result of the validation
3435
- name: Print result
Lines changed: 66 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,66 @@
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@v5
18-
with:
19-
ref: ${{ github.event.workflow_run.head_sha }}
20-
21-
- uses: codfish/semantic-release-action@v4
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) }}
1+
name: "Create Release"
2+
3+
on:
4+
push:
5+
branches: ["main"]
6+
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: write
11+
pull-requests: write
12+
13+
jobs:
14+
create-release:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Checkout repository
18+
uses: actions/checkout@v4
19+
with:
20+
ref: ${{ github.sha }}
21+
22+
- uses: codfish/semantic-release-action@v3
23+
id: semantic
24+
with:
25+
tag-format: 'v${version}'
26+
additional-packages: |
27+
['conventional-changelog-conventionalcommits@7']
28+
plugins: |
29+
[
30+
[
31+
"@semantic-release/commit-analyzer",
32+
{
33+
"preset": "conventionalcommits"
34+
}
35+
],
36+
[
37+
"@semantic-release/release-notes-generator",
38+
{
39+
"preset": "conventionalcommits",
40+
"presetConfig": {
41+
"types": [
42+
{ type: 'feat', section: 'Features', hidden: false },
43+
{ type: 'fix', section: 'Bug Fixes', hidden: false },
44+
{ type: 'perf', section: 'Performance Improvements', hidden: false },
45+
{ type: 'revert', section: 'Reverts', hidden: false },
46+
{ type: 'docs', section: 'Other Updates', hidden: false },
47+
{ type: 'style', section: 'Other Updates', hidden: false },
48+
{ type: 'chore', section: 'Other Updates', hidden: false },
49+
{ type: 'refactor', section: 'Other Updates', hidden: false },
50+
{ type: 'test', section: 'Other Updates', hidden: false },
51+
{ type: 'build', section: 'Other Updates', hidden: false },
52+
{ type: 'ci', section: 'Other Updates', hidden: false }
53+
]
54+
}
55+
}
56+
],
57+
'@semantic-release/github'
58+
]
59+
env:
60+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
61+
62+
- run: echo ${{ steps.semantic.outputs.release-version }}
63+
64+
- run: echo "$OUTPUTS"
65+
env:
66+
OUTPUTS: ${{ toJson(steps.semantic.outputs) }}

.github/workflows/deploy-linux.yml

Lines changed: 181 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -93,21 +93,191 @@ on:
9393

9494
schedule:
9595
- cron: '0 9,21 * * *' # Runs at 9:00 AM and 9:00 PM GMT
96-
96+
permissions:
97+
contents: read
98+
actions: read
9799
jobs:
100+
validate-inputs:
101+
runs-on: ubuntu-latest
102+
outputs:
103+
validation_passed: ${{ steps.validate.outputs.passed }}
104+
azure_location: ${{ steps.validate.outputs.azure_location }}
105+
resource_group_name: ${{ steps.validate.outputs.resource_group_name }}
106+
waf_enabled: ${{ steps.validate.outputs.waf_enabled }}
107+
exp: ${{ steps.validate.outputs.exp }}
108+
build_docker_image: ${{ steps.validate.outputs.build_docker_image }}
109+
cleanup_resources: ${{ steps.validate.outputs.cleanup_resources }}
110+
run_e2e_tests: ${{ steps.validate.outputs.run_e2e_tests }}
111+
azure_env_log_analytics_workspace_id: ${{ steps.validate.outputs.azure_env_log_analytics_workspace_id }}
112+
azure_existing_ai_project_resource_id: ${{ steps.validate.outputs.azure_existing_ai_project_resource_id }}
113+
existing_webapp_url: ${{ steps.validate.outputs.existing_webapp_url }}
114+
steps:
115+
- name: Validate Workflow Input Parameters
116+
id: validate
117+
shell: bash
118+
env:
119+
INPUT_AZURE_LOCATION: ${{ github.event.inputs.azure_location }}
120+
INPUT_RESOURCE_GROUP_NAME: ${{ github.event.inputs.resource_group_name }}
121+
INPUT_WAF_ENABLED: ${{ github.event.inputs.waf_enabled }}
122+
INPUT_EXP: ${{ github.event.inputs.EXP }}
123+
INPUT_BUILD_DOCKER_IMAGE: ${{ github.event.inputs.build_docker_image }}
124+
INPUT_CLEANUP_RESOURCES: ${{ github.event.inputs.cleanup_resources }}
125+
INPUT_RUN_E2E_TESTS: ${{ github.event.inputs.run_e2e_tests }}
126+
INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID: ${{ github.event.inputs.AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID }}
127+
INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID: ${{ github.event.inputs.AZURE_EXISTING_AI_PROJECT_RESOURCE_ID }}
128+
INPUT_EXISTING_WEBAPP_URL: ${{ github.event.inputs.existing_webapp_url }}
129+
run: |
130+
echo "🔍 Validating workflow input parameters..."
131+
VALIDATION_FAILED=false
132+
133+
# Validate azure_location (Azure region format)
134+
LOCATION="${INPUT_AZURE_LOCATION:-australiaeast}"
135+
136+
if [[ ! "$LOCATION" =~ ^[a-z0-9]+$ ]]; then
137+
echo "❌ ERROR: azure_location '$LOCATION' is invalid. Must contain only lowercase letters and numbers"
138+
VALIDATION_FAILED=true
139+
else
140+
echo "✅ azure_location: '$LOCATION' is valid"
141+
fi
142+
143+
# Validate resource_group_name (Azure naming convention, optional)
144+
if [[ -n "$INPUT_RESOURCE_GROUP_NAME" ]]; then
145+
if [[ ! "$INPUT_RESOURCE_GROUP_NAME" =~ ^[a-zA-Z0-9._\(\)-]+$ ]] || [[ "$INPUT_RESOURCE_GROUP_NAME" =~ \.$ ]]; then
146+
echo "❌ ERROR: resource_group_name '$INPUT_RESOURCE_GROUP_NAME' is invalid. Must contain only alphanumerics, periods, underscores, hyphens, and parentheses. Cannot end with period."
147+
VALIDATION_FAILED=true
148+
elif [[ ${#INPUT_RESOURCE_GROUP_NAME} -gt 90 ]]; then
149+
echo "❌ ERROR: resource_group_name '$INPUT_RESOURCE_GROUP_NAME' exceeds 90 characters (length: ${#INPUT_RESOURCE_GROUP_NAME})"
150+
VALIDATION_FAILED=true
151+
else
152+
echo "✅ resource_group_name: '$INPUT_RESOURCE_GROUP_NAME' is valid"
153+
fi
154+
else
155+
echo "✅ resource_group_name: Not provided (will be auto-generated)"
156+
fi
157+
158+
# Validate waf_enabled (boolean)
159+
WAF_ENABLED="${INPUT_WAF_ENABLED:-false}"
160+
if [[ "$WAF_ENABLED" != "true" && "$WAF_ENABLED" != "false" ]]; then
161+
echo "❌ ERROR: waf_enabled must be 'true' or 'false', got: '$WAF_ENABLED'"
162+
VALIDATION_FAILED=true
163+
else
164+
echo "✅ waf_enabled: '$WAF_ENABLED' is valid"
165+
fi
166+
167+
# Validate EXP (boolean)
168+
EXP_ENABLED="${INPUT_EXP:-false}"
169+
if [[ "$EXP_ENABLED" != "true" && "$EXP_ENABLED" != "false" ]]; then
170+
echo "❌ ERROR: EXP must be 'true' or 'false', got: '$EXP_ENABLED'"
171+
VALIDATION_FAILED=true
172+
else
173+
echo "✅ EXP: '$EXP_ENABLED' is valid"
174+
fi
175+
176+
# Validate build_docker_image (boolean)
177+
BUILD_DOCKER="${INPUT_BUILD_DOCKER_IMAGE:-false}"
178+
if [[ "$BUILD_DOCKER" != "true" && "$BUILD_DOCKER" != "false" ]]; then
179+
echo "❌ ERROR: build_docker_image must be 'true' or 'false', got: '$BUILD_DOCKER'"
180+
VALIDATION_FAILED=true
181+
else
182+
echo "✅ build_docker_image: '$BUILD_DOCKER' is valid"
183+
fi
184+
185+
# Validate cleanup_resources (boolean)
186+
CLEANUP_RESOURCES="${INPUT_CLEANUP_RESOURCES:-false}"
187+
if [[ "$CLEANUP_RESOURCES" != "true" && "$CLEANUP_RESOURCES" != "false" ]]; then
188+
echo "❌ ERROR: cleanup_resources must be 'true' or 'false', got: '$CLEANUP_RESOURCES'"
189+
VALIDATION_FAILED=true
190+
else
191+
echo "✅ cleanup_resources: '$CLEANUP_RESOURCES' is valid"
192+
fi
193+
194+
# Validate run_e2e_tests (specific allowed values)
195+
TEST_OPTION="${INPUT_RUN_E2E_TESTS:-GoldenPath-Testing}"
196+
if [[ "$TEST_OPTION" != "GoldenPath-Testing" && "$TEST_OPTION" != "Smoke-Testing" && "$TEST_OPTION" != "None" ]]; then
197+
echo "❌ ERROR: run_e2e_tests must be one of: GoldenPath-Testing, Smoke-Testing, None, got: '$TEST_OPTION'"
198+
VALIDATION_FAILED=true
199+
else
200+
echo "✅ run_e2e_tests: '$TEST_OPTION' is valid"
201+
fi
202+
203+
# Validate AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID (optional, Azure Resource ID format)
204+
if [[ -n "$INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID" ]]; then
205+
if [[ ! "$INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID" =~ ^/subscriptions/[a-fA-F0-9-]+/[Rr]esource[Gg]roups/[^/]+/providers/[Mm]icrosoft\.[Oo]perational[Ii]nsights/[Ww]orkspaces/[^/]+$ ]]; then
206+
echo "❌ ERROR: AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID is invalid. Must be a valid Azure Resource ID format:"
207+
echo " /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}"
208+
echo " Got: '$INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID'"
209+
VALIDATION_FAILED=true
210+
else
211+
echo "✅ AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID: Valid Resource ID format"
212+
fi
213+
else
214+
echo "✅ AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID: Not provided (optional)"
215+
fi
216+
217+
# Validate AZURE_EXISTING_AI_PROJECT_RESOURCE_ID (optional, Azure Resource ID format)
218+
if [[ -n "$INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID" ]]; then
219+
if [[ ! "$INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID" =~ ^/subscriptions/[a-fA-F0-9-]+/[Rr]esource[Gg]roups/[^/]+/providers/([Mm]icrosoft\.[Mm]achine[Ll]earning[Ss]ervices/([Ww]orkspaces|[Pp]rojects)/[^/]+|[Mm]icrosoft\.[Cc]ognitive[Ss]ervices/[Aa]ccounts/[^/]+/[Pp]rojects/[^/]+)$ ]]; then
220+
echo "❌ ERROR: AZURE_EXISTING_AI_PROJECT_RESOURCE_ID is invalid. Must be a valid Azure Resource ID format:"
221+
echo " /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CognitiveServices/accounts/{accountName}/projects/{projectName}"
222+
echo " Got: '$INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID'"
223+
VALIDATION_FAILED=true
224+
else
225+
echo "✅ AZURE_EXISTING_AI_PROJECT_RESOURCE_ID: Valid Resource ID format"
226+
fi
227+
else
228+
echo "✅ AZURE_EXISTING_AI_PROJECT_RESOURCE_ID: Not provided (optional)"
229+
fi
230+
231+
# Validate existing_webapp_url (optional, must start with https)
232+
if [[ -n "$INPUT_EXISTING_WEBAPP_URL" ]]; then
233+
if [[ ! "$INPUT_EXISTING_WEBAPP_URL" =~ ^https:// ]]; then
234+
echo "❌ ERROR: existing_webapp_url must start with 'https://', got: '$INPUT_EXISTING_WEBAPP_URL'"
235+
VALIDATION_FAILED=true
236+
else
237+
echo "✅ existing_webapp_url: '$INPUT_EXISTING_WEBAPP_URL' is valid"
238+
fi
239+
else
240+
echo "✅ existing_webapp_url: Not provided (will perform deployment)"
241+
fi
242+
243+
# Fail workflow if any validation failed
244+
if [[ "$VALIDATION_FAILED" == "true" ]]; then
245+
echo ""
246+
echo "❌ Parameter validation failed. Please correct the errors above and try again."
247+
exit 1
248+
fi
249+
250+
echo ""
251+
echo "✅ All input parameters validated successfully!"
252+
253+
# Output validated values
254+
echo "passed=true" >> $GITHUB_OUTPUT
255+
echo "azure_location=$LOCATION" >> $GITHUB_OUTPUT
256+
echo "resource_group_name=$INPUT_RESOURCE_GROUP_NAME" >> $GITHUB_OUTPUT
257+
echo "waf_enabled=$WAF_ENABLED" >> $GITHUB_OUTPUT
258+
echo "exp=$EXP_ENABLED" >> $GITHUB_OUTPUT
259+
echo "build_docker_image=$BUILD_DOCKER" >> $GITHUB_OUTPUT
260+
echo "cleanup_resources=$CLEANUP_RESOURCES" >> $GITHUB_OUTPUT
261+
echo "run_e2e_tests=$TEST_OPTION" >> $GITHUB_OUTPUT
262+
echo "azure_env_log_analytics_workspace_id=$INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID" >> $GITHUB_OUTPUT
263+
echo "azure_existing_ai_project_resource_id=$INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID" >> $GITHUB_OUTPUT
264+
echo "existing_webapp_url=$INPUT_EXISTING_WEBAPP_URL" >> $GITHUB_OUTPUT
265+
98266
Run:
267+
needs: validate-inputs
268+
if: needs.validate-inputs.outputs.validation_passed == 'true'
99269
uses: ./.github/workflows/deploy-orchestrator.yml
100270
with:
101271
runner_os: ubuntu-latest
102-
azure_location: ${{ github.event.inputs.azure_location || 'australiaeast' }}
103-
resource_group_name: ${{ github.event.inputs.resource_group_name || '' }}
104-
waf_enabled: ${{ github.event.inputs.waf_enabled == 'true' }}
105-
EXP: ${{ github.event.inputs.EXP == 'true' }}
106-
build_docker_image: ${{ github.event.inputs.build_docker_image == 'true' }}
107-
cleanup_resources: ${{ github.event.inputs.cleanup_resources == 'true' }}
108-
run_e2e_tests: ${{ github.event.inputs.run_e2e_tests || 'GoldenPath-Testing' }}
109-
AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID: ${{ github.event.inputs.AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID || '' }}
110-
AZURE_EXISTING_AI_PROJECT_RESOURCE_ID: ${{ github.event.inputs.AZURE_EXISTING_AI_PROJECT_RESOURCE_ID || '' }}
111-
existing_webapp_url: ${{ github.event.inputs.existing_webapp_url || '' }}
272+
azure_location: ${{ needs.validate-inputs.outputs.azure_location || 'australiaeast' }}
273+
resource_group_name: ${{ needs.validate-inputs.outputs.resource_group_name || '' }}
274+
waf_enabled: ${{ needs.validate-inputs.outputs.waf_enabled == 'true' }}
275+
EXP: ${{ needs.validate-inputs.outputs.exp == 'true' }}
276+
build_docker_image: ${{ needs.validate-inputs.outputs.build_docker_image == 'true' }}
277+
cleanup_resources: ${{ needs.validate-inputs.outputs.cleanup_resources == 'true' }}
278+
run_e2e_tests: ${{ needs.validate-inputs.outputs.run_e2e_tests || 'GoldenPath-Testing' }}
279+
AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID: ${{ needs.validate-inputs.outputs.azure_env_log_analytics_workspace_id || '' }}
280+
AZURE_EXISTING_AI_PROJECT_RESOURCE_ID: ${{ needs.validate-inputs.outputs.azure_existing_ai_project_resource_id || '' }}
281+
existing_webapp_url: ${{ needs.validate-inputs.outputs.existing_webapp_url || '' }}
112282
trigger_type: ${{ github.event_name }}
113283
secrets: inherit

0 commit comments

Comments
 (0)