Skip to content

Commit 580354f

Browse files
Added validation step for Inputs and Map Inputs to env
1 parent c343b2f commit 580354f

4 files changed

Lines changed: 766 additions & 72 deletions

File tree

.github/workflows/job-azure-deploy.yml

Lines changed: 209 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -116,18 +116,190 @@ jobs:
116116
QUOTA_FAILED: ${{ steps.quota_failure_output.outputs.QUOTA_FAILED }}
117117

118118
steps:
119+
- name: Validate Workflow Input Parameters
120+
shell: bash
121+
env:
122+
INPUT_TRIGGER_TYPE: ${{ inputs.trigger_type }}
123+
INPUT_RUNNER_OS: ${{ inputs.runner_os }}
124+
INPUT_BUILD_DOCKER_IMAGE: ${{ inputs.build_docker_image }}
125+
INPUT_AZURE_LOCATION: ${{ inputs.azure_location }}
126+
INPUT_RESOURCE_GROUP_NAME: ${{ inputs.resource_group_name }}
127+
INPUT_WAF_ENABLED: ${{ inputs.waf_enabled }}
128+
INPUT_EXP: ${{ inputs.exp }}
129+
INPUT_CLEANUP_RESOURCES: ${{ inputs.cleanup_resources }}
130+
INPUT_RUN_E2E_TESTS: ${{ inputs.run_e2e_tests }}
131+
INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID: ${{ inputs.azure_env_log_anlytics_workspace_id }}
132+
INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID: ${{ inputs.azure_existing_ai_project_resource_id }}
133+
INPUT_EXISTING_WEBAPP_URL: ${{ inputs.existing_webapp_url }}
134+
INPUT_DOCKER_IMAGE_TAG: ${{ inputs.docker_image_tag }}
135+
run: |
136+
echo "🔍 Validating workflow input parameters..."
137+
VALIDATION_FAILED=false
138+
139+
# Validate trigger_type (required - alphanumeric with underscores)
140+
if [[ -z "$INPUT_TRIGGER_TYPE" ]]; then
141+
echo "❌ ERROR: trigger_type is required but was not provided"
142+
VALIDATION_FAILED=true
143+
elif [[ ! "$INPUT_TRIGGER_TYPE" =~ ^[a-zA-Z0-9_]+$ ]]; then
144+
echo "❌ ERROR: trigger_type '$INPUT_TRIGGER_TYPE' is invalid. Must contain only alphanumeric characters and underscores"
145+
VALIDATION_FAILED=true
146+
else
147+
echo "✅ trigger_type: '$INPUT_TRIGGER_TYPE' is valid"
148+
fi
149+
150+
# Validate runner_os (required - must be specific values)
151+
ALLOWED_RUNNER_OS=("ubuntu-latest" "windows-latest")
152+
if [[ -z "$INPUT_RUNNER_OS" ]]; then
153+
echo "❌ ERROR: runner_os is required but was not provided"
154+
VALIDATION_FAILED=true
155+
elif [[ ! " ${ALLOWED_RUNNER_OS[@]} " =~ " ${INPUT_RUNNER_OS} " ]]; then
156+
echo "❌ ERROR: runner_os '$INPUT_RUNNER_OS' is invalid. Allowed values: ${ALLOWED_RUNNER_OS[*]}"
157+
VALIDATION_FAILED=true
158+
else
159+
echo "✅ runner_os: '$INPUT_RUNNER_OS' is valid"
160+
fi
161+
162+
# Validate build_docker_image (boolean)
163+
if [[ "$INPUT_BUILD_DOCKER_IMAGE" != "true" && "$INPUT_BUILD_DOCKER_IMAGE" != "false" ]]; then
164+
echo "❌ ERROR: build_docker_image must be 'true' or 'false', got: '$INPUT_BUILD_DOCKER_IMAGE'"
165+
VALIDATION_FAILED=true
166+
else
167+
echo "✅ build_docker_image: '$INPUT_BUILD_DOCKER_IMAGE' is valid"
168+
fi
169+
170+
# Validate azure_location (Azure region format)
171+
if [[ -n "$INPUT_AZURE_LOCATION" ]]; then
172+
if [[ ! "$INPUT_AZURE_LOCATION" =~ ^[a-z0-9]+$ ]]; then
173+
echo "❌ ERROR: azure_location '$INPUT_AZURE_LOCATION' is invalid. Must contain only lowercase letters and numbers (e.g., 'australiaeast', 'westus2')"
174+
VALIDATION_FAILED=true
175+
else
176+
echo "✅ azure_location: '$INPUT_AZURE_LOCATION' is valid"
177+
fi
178+
fi
179+
180+
# Validate resource_group_name (Azure resource group naming convention)
181+
if [[ -n "$INPUT_RESOURCE_GROUP_NAME" ]]; then
182+
if [[ ! "$INPUT_RESOURCE_GROUP_NAME" =~ ^[a-zA-Z0-9._\(\)-]+$ ]] || [[ "$INPUT_RESOURCE_GROUP_NAME" =~ \.$ ]]; then
183+
echo "❌ ERROR: resource_group_name '$INPUT_RESOURCE_GROUP_NAME' is invalid. Must contain only alphanumerics, periods, underscores, hyphens, and parentheses. Cannot end with period."
184+
VALIDATION_FAILED=true
185+
elif [[ ${#INPUT_RESOURCE_GROUP_NAME} -gt 90 ]]; then
186+
echo "❌ ERROR: resource_group_name '$INPUT_RESOURCE_GROUP_NAME' exceeds 90 characters"
187+
VALIDATION_FAILED=true
188+
else
189+
echo "✅ resource_group_name: '$INPUT_RESOURCE_GROUP_NAME' is valid"
190+
fi
191+
fi
192+
193+
# Validate waf_enabled (boolean)
194+
if [[ "$INPUT_WAF_ENABLED" != "true" && "$INPUT_WAF_ENABLED" != "false" ]]; then
195+
echo "❌ ERROR: waf_enabled must be 'true' or 'false', got: '$INPUT_WAF_ENABLED'"
196+
VALIDATION_FAILED=true
197+
else
198+
echo "✅ waf_enabled: '$INPUT_WAF_ENABLED' is valid"
199+
fi
200+
201+
# Validate EXP (boolean)
202+
if [[ "$INPUT_EXP" != "true" && "$INPUT_EXP" != "false" ]]; then
203+
echo "❌ ERROR: EXP must be 'true' or 'false', got: '$INPUT_EXP'"
204+
VALIDATION_FAILED=true
205+
else
206+
echo "✅ EXP: '$INPUT_EXP' is valid"
207+
fi
208+
209+
# Validate cleanup_resources (boolean)
210+
if [[ "$INPUT_CLEANUP_RESOURCES" != "true" && "$INPUT_CLEANUP_RESOURCES" != "false" ]]; then
211+
echo "❌ ERROR: cleanup_resources must be 'true' or 'false', got: '$INPUT_CLEANUP_RESOURCES'"
212+
VALIDATION_FAILED=true
213+
else
214+
echo "✅ cleanup_resources: '$INPUT_CLEANUP_RESOURCES' is valid"
215+
fi
216+
217+
# Validate run_e2e_tests (specific allowed values)
218+
if [[ -n "$INPUT_RUN_E2E_TESTS" ]]; then
219+
ALLOWED_VALUES=("None" "GoldenPath-Testing" "Smoke-Testing")
220+
if [[ ! " ${ALLOWED_VALUES[@]} " =~ " ${INPUT_RUN_E2E_TESTS} " ]]; then
221+
echo "❌ ERROR: run_e2e_tests '$INPUT_RUN_E2E_TESTS' is invalid. Allowed values: ${ALLOWED_VALUES[*]}"
222+
VALIDATION_FAILED=true
223+
else
224+
echo "✅ run_e2e_tests: '$INPUT_RUN_E2E_TESTS' is valid"
225+
fi
226+
fi
227+
228+
# Validate AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID (Azure Resource ID format)
229+
if [[ -n "$INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID" ]]; then
230+
if [[ ! "$INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID" =~ ^/subscriptions/[a-fA-F0-9-]+/resourceGroups/[^/]+/providers/microsoft\.operationalinsights/workspaces/[^/]+$ ]]; then
231+
echo "❌ ERROR: AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID is invalid. Must be a valid Azure Resource ID format:"
232+
echo " /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}"
233+
echo " Got: '$INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID'"
234+
VALIDATION_FAILED=true
235+
else
236+
echo "✅ AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID: Valid Resource ID format"
237+
fi
238+
fi
239+
240+
# Validate AZURE_EXISTING_AI_PROJECT_RESOURCE_ID (Azure Resource ID format)
241+
if [[ -n "$INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID" ]]; then
242+
if [[ ! "$INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID" =~ ^/subscriptions/[a-fA-F0-9-]+/resourceGroups/[^/]+/providers/(Microsoft\.MachineLearningServices/(workspaces|projects)/[^/]+|Microsoft\.CognitiveServices/accounts/[^/]+/projects/[^/]+)$ ]]; then
243+
echo "❌ ERROR: AZURE_EXISTING_AI_PROJECT_RESOURCE_ID is invalid. Must be a valid Azure Resource ID format:"
244+
echo " /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CognitiveServices/accounts/{accountName}/projects/{projectName}"
245+
echo " Got: '$INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID'"
246+
VALIDATION_FAILED=true
247+
else
248+
echo "✅ AZURE_EXISTING_AI_PROJECT_RESOURCE_ID: Valid Resource ID format"
249+
fi
250+
fi
251+
252+
# Validate existing_webapp_url (must start with https)
253+
if [[ -n "$INPUT_EXISTING_WEBAPP_URL" ]]; then
254+
if [[ ! "$INPUT_EXISTING_WEBAPP_URL" =~ ^https:// ]]; then
255+
echo "❌ ERROR: existing_webapp_url must start with 'https://', got: '$INPUT_EXISTING_WEBAPP_URL'"
256+
VALIDATION_FAILED=true
257+
else
258+
echo "✅ existing_webapp_url: '$INPUT_EXISTING_WEBAPP_URL' is valid"
259+
fi
260+
fi
261+
262+
# Validate docker_image_tag (Docker tag pattern)
263+
if [[ -n "$INPUT_DOCKER_IMAGE_TAG" ]]; then
264+
# Docker tags: lowercase and uppercase letters, digits, underscores, periods, and hyphens
265+
# Cannot start with period or hyphen, max 128 characters
266+
if [[ ! "$INPUT_DOCKER_IMAGE_TAG" =~ ^[a-zA-Z0-9_][a-zA-Z0-9._-]{0,127}$ ]]; then
267+
echo "❌ ERROR: docker_image_tag '$INPUT_DOCKER_IMAGE_TAG' is invalid. Must:"
268+
echo " - Start with alphanumeric or underscore"
269+
echo " - Contain only alphanumerics, underscores, periods, hyphens"
270+
echo " - Be max 128 characters"
271+
VALIDATION_FAILED=true
272+
else
273+
echo "✅ docker_image_tag: '$INPUT_DOCKER_IMAGE_TAG' is valid"
274+
fi
275+
fi
276+
277+
# Fail workflow if any validation failed
278+
if [[ "$VALIDATION_FAILED" == "true" ]]; then
279+
echo ""
280+
echo "❌ Parameter validation failed. Please correct the errors above and try again."
281+
exit 1
282+
fi
283+
284+
echo ""
285+
echo "✅ All input parameters validated successfully!"
286+
119287
- name: Validate and Auto-Configure EXP
120288
shell: bash
289+
env:
290+
INPUT_EXP: ${{ inputs.exp }}
291+
INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID: ${{ inputs.azure_env_log_anlytics_workspace_id }}
292+
INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID: ${{ inputs.azure_existing_ai_project_resource_id }}
121293
run: |
122294
echo "🔍 Validating EXP configuration..."
123295
124-
if [[ "${{ inputs.exp }}" != "true" ]]; then
125-
if [[ -n "${{ inputs.azure_env_log_anlytics_workspace_id }}" ]] || [[ -n "${{ inputs.azure_existing_ai_project_resource_id }}" ]]; then
296+
if [[ "$INPUT_EXP" != "true" ]]; then
297+
if [[ -n "$INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID" ]] || [[ -n "$INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID" ]]; then
126298
echo "🔧 AUTO-ENABLING EXP: EXP parameter values were provided but EXP was not explicitly enabled."
127299
echo ""
128300
echo "You provided values for:"
129-
[[ -n "${{ inputs.azure_env_log_anlytics_workspace_id }}" ]] && echo " - Azure Log Analytics Workspace ID: '${{ inputs.azure_env_log_anlytics_workspace_id }}'"
130-
[[ -n "${{ inputs.azure_existing_ai_project_resource_id }}" ]] && echo " - Azure AI Project Resource ID: '${{ inputs.azure_existing_ai_project_resource_id }}'"
301+
[[ -n "$INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID" ]] && echo " - Azure Log Analytics Workspace ID: '$INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID'"
302+
[[ -n "$INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID" ]] && echo " - Azure AI Project Resource ID: '$INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID'"
131303
echo ""
132304
echo "✅ Automatically enabling EXP to use these values."
133305
echo "EXP=true" >> $GITHUB_ENV
@@ -180,13 +352,16 @@ jobs:
180352
- name: Set Deployment Region
181353
id: set_region
182354
shell: bash
355+
env:
356+
INPUT_TRIGGER_TYPE: ${{ inputs.trigger_type }}
357+
INPUT_AZURE_LOCATION: ${{ inputs.azure_location }}
183358
run: |
184359
echo "Selected Region from Quota Check: $VALID_REGION"
185360
echo "AZURE_ENV_OPENAI_LOCATION=$VALID_REGION" >> $GITHUB_ENV
186361
echo "AZURE_ENV_OPENAI_LOCATION=$VALID_REGION" >> $GITHUB_OUTPUT
187362
188-
if [[ "${{ inputs.trigger_type }}" == "workflow_dispatch" && -n "${{ inputs.azure_location }}" ]]; then
189-
USER_SELECTED_LOCATION="${{ inputs.azure_location }}"
363+
if [[ "$INPUT_TRIGGER_TYPE" == "workflow_dispatch" && -n "$INPUT_AZURE_LOCATION" ]]; then
364+
USER_SELECTED_LOCATION="$INPUT_AZURE_LOCATION"
190365
echo "Using user-selected Azure location: $USER_SELECTED_LOCATION"
191366
echo "AZURE_LOCATION=$USER_SELECTED_LOCATION" >> $GITHUB_ENV
192367
echo "AZURE_LOCATION=$USER_SELECTED_LOCATION" >> $GITHUB_OUTPUT
@@ -199,11 +374,13 @@ jobs:
199374
- name: Generate Resource Group Name
200375
id: generate_rg_name
201376
shell: bash
377+
env:
378+
INPUT_RESOURCE_GROUP_NAME: ${{ inputs.resource_group_name }}
202379
run: |
203380
# Check if a resource group name was provided as input
204-
if [[ -n "${{ inputs.resource_group_name }}" ]]; then
205-
echo "Using provided Resource Group name: ${{ inputs.resource_group_name }}"
206-
echo "RESOURCE_GROUP_NAME=${{ inputs.resource_group_name }}" >> $GITHUB_ENV
381+
if [[ -n "$INPUT_RESOURCE_GROUP_NAME" ]]; then
382+
echo "Using provided Resource Group name: $INPUT_RESOURCE_GROUP_NAME"
383+
echo "RESOURCE_GROUP_NAME=$INPUT_RESOURCE_GROUP_NAME" >> $GITHUB_ENV
207384
else
208385
echo "Generating a unique resource group name..."
209386
ACCL_NAME="kmgeneric" # Account name as specified
@@ -245,10 +422,12 @@ jobs:
245422
- name: Determine Docker Image Tag
246423
id: determine_image_tag
247424
shell: bash
425+
env:
426+
INPUT_DOCKER_IMAGE_TAG: ${{ inputs.docker_image_tag }}
248427
run: |
249428
if [[ "${{ env.BUILD_DOCKER_IMAGE }}" == "true" ]]; then
250-
if [[ -n "${{ inputs.docker_image_tag }}" ]]; then
251-
IMAGE_TAG="${{ inputs.docker_image_tag }}"
429+
if [[ -n "$INPUT_DOCKER_IMAGE_TAG" ]]; then
430+
IMAGE_TAG="$INPUT_DOCKER_IMAGE_TAG"
252431
echo "🔗 Using Docker image tag from build job: $IMAGE_TAG"
253432
else
254433
echo "❌ Docker build job failed or was skipped, but BUILD_DOCKER_IMAGE is true"
@@ -297,33 +476,42 @@ jobs:
297476
298477
- name: Display Workflow Configuration to GitHub Summary
299478
shell: bash
479+
env:
480+
INPUT_TRIGGER_TYPE: ${{ inputs.trigger_type }}
481+
INPUT_RUNNER_OS: ${{ inputs.runner_os }}
482+
INPUT_AZURE_LOCATION: ${{ inputs.azure_location }}
483+
INPUT_RESOURCE_GROUP_NAME: ${{ inputs.resource_group_name }}
484+
WAF_ENABLED_DISPLAY: ${{ env.WAF_ENABLED == 'true' && '✅ Yes' || '❌ No' }}
485+
EXP_DISPLAY: ${{ env.EXP == 'true' && '✅ Yes' || '❌ No' }}
486+
CLEANUP_DISPLAY: ${{ env.CLEANUP_RESOURCES == 'true' && '✅ Yes' || '❌ No' }}
487+
BUILD_DOCKER_DISPLAY: ${{ env.BUILD_DOCKER_IMAGE == 'true' && '✅ Yes' || '❌ No' }}
300488
run: |
301489
echo "## 📋 Workflow Configuration Summary" >> $GITHUB_STEP_SUMMARY
302490
echo "" >> $GITHUB_STEP_SUMMARY
303491
echo "| Configuration | Value |" >> $GITHUB_STEP_SUMMARY
304492
echo "|---------------|-------|" >> $GITHUB_STEP_SUMMARY
305493
echo "| **Trigger Type** | \`${{ github.event_name }}\` |" >> $GITHUB_STEP_SUMMARY
306494
echo "| **Branch** | \`${{ env.BRANCH_NAME }}\` |" >> $GITHUB_STEP_SUMMARY
307-
echo "| **Runner OS** | \`${{ inputs.runner_os }}\` |" >> $GITHUB_STEP_SUMMARY
308-
echo "| **WAF Enabled** | ${{ env.WAF_ENABLED == 'true' && '✅ Yes' || '❌ No' }} |" >> $GITHUB_STEP_SUMMARY
309-
echo "| **EXP Enabled** | ${{ env.EXP == 'true' && '✅ Yes' || '❌ No' }} |" >> $GITHUB_STEP_SUMMARY
495+
echo "| **Runner OS** | \`$INPUT_RUNNER_OS\` |" >> $GITHUB_STEP_SUMMARY
496+
echo "| **WAF Enabled** | $WAF_ENABLED_DISPLAY |" >> $GITHUB_STEP_SUMMARY
497+
echo "| **EXP Enabled** | $EXP_DISPLAY |" >> $GITHUB_STEP_SUMMARY
310498
echo "| **Run E2E Tests** | \`${{ env.RUN_E2E_TESTS }}\` |" >> $GITHUB_STEP_SUMMARY
311-
echo "| **Cleanup Resources** | ${{ env.CLEANUP_RESOURCES == 'true' && '✅ Yes' || '❌ No' }} |" >> $GITHUB_STEP_SUMMARY
312-
echo "| **Build Docker Image** | ${{ env.BUILD_DOCKER_IMAGE == 'true' && '✅ Yes' || '❌ No' }} |" >> $GITHUB_STEP_SUMMARY
499+
echo "| **Cleanup Resources** | $CLEANUP_DISPLAY |" >> $GITHUB_STEP_SUMMARY
500+
echo "| **Build Docker Image** | $BUILD_DOCKER_DISPLAY |" >> $GITHUB_STEP_SUMMARY
313501
314-
if [[ "${{ inputs.trigger_type }}" == "workflow_dispatch" && -n "${{ inputs.azure_location }}" ]]; then
315-
echo "| **Azure Location** | \`${{ inputs.azure_location }}\` (User Selected) |" >> $GITHUB_STEP_SUMMARY
502+
if [[ "$INPUT_TRIGGER_TYPE" == "workflow_dispatch" && -n "$INPUT_AZURE_LOCATION" ]]; then
503+
echo "| **Azure Location** | \`$INPUT_AZURE_LOCATION\` (User Selected) |" >> $GITHUB_STEP_SUMMARY
316504
fi
317505
318-
if [[ -n "${{ inputs.resource_group_name }}" ]]; then
319-
echo "| **Resource Group** | \`${{ inputs.resource_group_name }}\` (Pre-specified) |" >> $GITHUB_STEP_SUMMARY
506+
if [[ -n "$INPUT_RESOURCE_GROUP_NAME" ]]; then
507+
echo "| **Resource Group** | \`$INPUT_RESOURCE_GROUP_NAME\` (Pre-specified) |" >> $GITHUB_STEP_SUMMARY
320508
else
321509
echo "| **Resource Group** | \`${{ env.RESOURCE_GROUP_NAME }}\` (Auto-generated) |" >> $GITHUB_STEP_SUMMARY
322510
fi
323511
324512
echo "" >> $GITHUB_STEP_SUMMARY
325513
326-
if [[ "${{ inputs.trigger_type }}" != "workflow_dispatch" ]]; then
514+
if [[ "$INPUT_TRIGGER_TYPE" != "workflow_dispatch" ]]; then
327515
echo "ℹ️ **Note:** Automatic Trigger - Using Non-WAF + Non-EXP configuration" >> $GITHUB_STEP_SUMMARY
328516
else
329517
echo "ℹ️ **Note:** Manual Trigger - Using user-specified configuration" >> $GITHUB_STEP_SUMMARY

0 commit comments

Comments
 (0)