Skip to content

Commit ec27847

Browse files
Merge pull request #751 from microsoft/main
fix: down merge to dev from main
2 parents 885188c + 48874c9 commit ec27847

File tree

11 files changed

+579
-96
lines changed

11 files changed

+579
-96
lines changed

.github/workflows/deploy-linux.yml

Lines changed: 206 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ on:
4646
required: false
4747
default: false
4848
type: boolean
49-
exp:
49+
EXP:
5050
description: 'Enable EXP'
5151
required: false
5252
default: false
@@ -61,6 +61,14 @@ on:
6161
required: false
6262
default: false
6363
type: boolean
64+
AZURE_ENV_USE_CASE:
65+
description: 'Specify Use case to deploy'
66+
type: 'choice'
67+
options:
68+
- 'telecom'
69+
- 'IT_helpdesk'
70+
required: false
71+
default: 'telecom'
6472
run_e2e_tests:
6573
description: 'Run End-to-End Tests'
6674
required: false
@@ -70,12 +78,12 @@ on:
7078
- 'GoldenPath-Testing'
7179
- 'Smoke-Testing'
7280
- 'None'
73-
azure_env_log_anlytics_workspace_id:
81+
AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID:
7482
description: 'Log Analytics Workspace ID (Optional)'
7583
required: false
7684
default: ''
7785
type: string
78-
azure_existing_ai_project_resource_id:
86+
AZURE_EXISTING_AI_PROJECT_RESOURCE_ID:
7987
description: 'AI Project Resource ID (Optional)'
8088
required: false
8189
default: ''
@@ -85,25 +93,210 @@ on:
8593
required: false
8694
default: ''
8795
type: string
96+
8897

8998
permissions:
9099
contents: read
91100
actions: read
92101

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

.github/workflows/deploy-orchestrator.yml

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ on:
4242
required: false
4343
default: 'GoldenPath-Testing'
4444
type: string
45-
azure_env_log_anlytics_workspace_id:
45+
azure_env_log_analytics_workspace_id:
4646
description: 'Log Analytics Workspace ID (Optional)'
4747
required: false
4848
default: ''
@@ -57,6 +57,11 @@ on:
5757
required: false
5858
default: ''
5959
type: string
60+
azure_env_use_case:
61+
description: 'Azure Environment Use Case (telecom or IT_helpdesk)'
62+
required: false
63+
default: 'telecom'
64+
type: string
6065
trigger_type:
6166
description: 'Trigger type (workflow_dispatch, pull_request, schedule)'
6267
required: true
@@ -74,7 +79,7 @@ jobs:
7479
secrets: inherit
7580

7681
deploy:
77-
if: always() && (inputs.trigger_type != 'workflow_dispatch' || inputs.existing_webapp_url == '' || inputs.existing_webapp_url == null)
82+
if: "!cancelled() && (needs.docker-build.result == 'success' || needs.docker-build.result == 'skipped') && (inputs.trigger_type != 'workflow_dispatch' || inputs.existing_webapp_url == '' || inputs.existing_webapp_url == null)"
7883
needs: docker-build
7984
uses: ./.github/workflows/job-azure-deploy.yml
8085
with:
@@ -86,25 +91,27 @@ jobs:
8691
exp: ${{ inputs.exp }}
8792
build_docker_image: ${{ inputs.build_docker_image }}
8893
existing_webapp_url: ${{ inputs.existing_webapp_url }}
89-
azure_env_log_anlytics_workspace_id: ${{ inputs.azure_env_log_anlytics_workspace_id }}
94+
azure_env_log_analytics_workspace_id: ${{ inputs.azure_env_log_analytics_workspace_id }}
9095
azure_existing_ai_project_resource_id: ${{ inputs.azure_existing_ai_project_resource_id }}
96+
azure_env_use_case: ${{ inputs.azure_env_use_case }}
9197
docker_image_tag: ${{ needs.docker-build.outputs.IMAGE_TAG }}
9298
run_e2e_tests: ${{ inputs.run_e2e_tests }}
9399
cleanup_resources: ${{ inputs.cleanup_resources }}
94100
secrets: inherit
95101

96102
e2e-test:
97-
if: always() && ((needs.deploy.result == 'success' && needs.deploy.outputs.WEB_APP_URL != '') || (inputs.existing_webapp_url != '' && inputs.existing_webapp_url != null)) && (inputs.trigger_type != 'workflow_dispatch' || (inputs.run_e2e_tests != 'None' && inputs.run_e2e_tests != '' && inputs.run_e2e_tests != null))
103+
if: false # E2E testing disabled
98104
needs: [docker-build, deploy]
99105
uses: ./.github/workflows/job-test-automation.yml
100106
with:
101107
KMGENERIC_URL: ${{ needs.deploy.outputs.WEB_APP_URL || inputs.existing_webapp_url }}
102108
KMGENERIC_URL_API: ${{ needs.deploy.outputs.API_APP_URL || inputs.existing_webapp_url }}
103109
TEST_SUITE: ${{ inputs.trigger_type == 'workflow_dispatch' && inputs.run_e2e_tests || 'GoldenPath-Testing' }}
110+
AZURE_ENV_USE_CASE: ${{ inputs.azure_env_use_case }}
104111
secrets: inherit
105112

106113
send-notification:
107-
if: always()
114+
if: "!cancelled()"
108115
needs: [docker-build, deploy, e2e-test]
109116
uses: ./.github/workflows/job-send-notifications.yml
110117
with:
@@ -123,7 +130,7 @@ jobs:
123130
secrets: inherit
124131

125132
cleanup-deployment:
126-
if: always() && needs.deploy.result == 'success' && needs.deploy.outputs.RESOURCE_GROUP_NAME != '' && inputs.existing_webapp_url == '' && (inputs.trigger_type != 'workflow_dispatch' || inputs.cleanup_resources)
133+
if: "!cancelled() && needs.deploy.outputs.RESOURCE_GROUP_NAME != '' && inputs.existing_webapp_url == '' && (inputs.trigger_type != 'workflow_dispatch' || inputs.cleanup_resources)"
127134
needs: [docker-build, deploy, e2e-test]
128135
uses: ./.github/workflows/job-cleanup-resources.yml
129136
with:

0 commit comments

Comments
 (0)