Deploy-Test-Cleanup (v2) Linux #127
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Deploy-Test-Cleanup (v2) Linux | |
| permissions: | |
| contents: read | |
| actions: read | |
| on: | |
| workflow_run: | |
| workflows: ["Build Docker and Optional Push v4"] | |
| types: | |
| - completed | |
| branches: | |
| - main | |
| - dev-v4 | |
| - hotfix | |
| workflow_dispatch: | |
| inputs: | |
| azure_location: | |
| description: 'Azure Location For Deployment' | |
| required: false | |
| default: 'australiaeast' | |
| type: choice | |
| options: | |
| - 'australiaeast' | |
| - 'centralus' | |
| - 'eastasia' | |
| - 'eastus2' | |
| - 'japaneast' | |
| - 'northeurope' | |
| - 'southeastasia' | |
| - 'uksouth' | |
| resource_group_name: | |
| description: 'Resource Group Name (Optional)' | |
| required: false | |
| default: '' | |
| type: string | |
| waf_enabled: | |
| description: 'Enable WAF' | |
| required: false | |
| default: false | |
| type: boolean | |
| EXP: | |
| description: 'Enable EXP' | |
| required: false | |
| default: false | |
| type: boolean | |
| build_docker_image: | |
| description: 'Build & Push Docker Image (Optional)' | |
| required: false | |
| default: false | |
| type: boolean | |
| cleanup_resources: | |
| description: 'Cleanup Deployed Resources' | |
| required: false | |
| default: false | |
| type: boolean | |
| run_e2e_tests: | |
| description: 'Run End-to-End Tests' | |
| required: false | |
| default: 'GoldenPath-Testing' | |
| type: choice | |
| options: | |
| - 'GoldenPath-Testing' | |
| - 'Smoke-Testing' | |
| - 'None' | |
| AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID: | |
| description: 'Log Analytics Workspace ID (Optional)' | |
| required: false | |
| default: '' | |
| type: string | |
| AZURE_EXISTING_AI_PROJECT_RESOURCE_ID: | |
| description: 'AI Project Resource ID (Optional)' | |
| required: false | |
| default: '' | |
| type: string | |
| existing_webapp_url: | |
| description: 'Existing WebApp URL (Skips Deployment)' | |
| required: false | |
| default: '' | |
| type: string | |
| schedule: | |
| - cron: "0 11,23 * * *" # Runs at 11:00 AM and 11:00 PM GMT | |
| jobs: | |
| validate-inputs: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| validation_passed: ${{ steps.validate.outputs.passed }} | |
| azure_location: ${{ steps.validate.outputs.azure_location }} | |
| resource_group_name: ${{ steps.validate.outputs.resource_group_name }} | |
| waf_enabled: ${{ steps.validate.outputs.waf_enabled }} | |
| exp: ${{ steps.validate.outputs.exp }} | |
| build_docker_image: ${{ steps.validate.outputs.build_docker_image }} | |
| cleanup_resources: ${{ steps.validate.outputs.cleanup_resources }} | |
| run_e2e_tests: ${{ steps.validate.outputs.run_e2e_tests }} | |
| azure_env_log_analytics_workspace_id: ${{ steps.validate.outputs.azure_env_log_analytics_workspace_id }} | |
| azure_existing_ai_project_resource_id: ${{ steps.validate.outputs.azure_existing_ai_project_resource_id }} | |
| existing_webapp_url: ${{ steps.validate.outputs.existing_webapp_url }} | |
| steps: | |
| - name: Validate Workflow Input Parameters | |
| id: validate | |
| shell: bash | |
| env: | |
| INPUT_AZURE_LOCATION: ${{ github.event.inputs.azure_location }} | |
| INPUT_RESOURCE_GROUP_NAME: ${{ github.event.inputs.resource_group_name }} | |
| INPUT_WAF_ENABLED: ${{ github.event.inputs.waf_enabled }} | |
| INPUT_EXP: ${{ github.event.inputs.EXP }} | |
| INPUT_BUILD_DOCKER_IMAGE: ${{ github.event.inputs.build_docker_image }} | |
| INPUT_CLEANUP_RESOURCES: ${{ github.event.inputs.cleanup_resources }} | |
| INPUT_RUN_E2E_TESTS: ${{ github.event.inputs.run_e2e_tests }} | |
| INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID: ${{ github.event.inputs.AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID }} | |
| INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID: ${{ github.event.inputs.AZURE_EXISTING_AI_PROJECT_RESOURCE_ID }} | |
| INPUT_EXISTING_WEBAPP_URL: ${{ github.event.inputs.existing_webapp_url }} | |
| run: | | |
| echo "🔍 Validating workflow input parameters..." | |
| VALIDATION_FAILED=false | |
| # Validate azure_location (Azure region format) | |
| LOCATION="${INPUT_AZURE_LOCATION:-australiaeast}" | |
| if [[ ! "$LOCATION" =~ ^[a-z0-9]+$ ]]; then | |
| echo "❌ ERROR: azure_location '$LOCATION' is invalid. Must contain only lowercase letters and numbers" | |
| VALIDATION_FAILED=true | |
| else | |
| echo "✅ azure_location: '$LOCATION' is valid" | |
| fi | |
| # Validate resource_group_name (Azure naming convention, optional) | |
| if [[ -n "$INPUT_RESOURCE_GROUP_NAME" ]]; then | |
| if [[ ! "$INPUT_RESOURCE_GROUP_NAME" =~ ^[a-zA-Z0-9._\(\)-]+$ ]] || [[ "$INPUT_RESOURCE_GROUP_NAME" =~ \.$ ]]; then | |
| echo "❌ ERROR: resource_group_name '$INPUT_RESOURCE_GROUP_NAME' is invalid. Must contain only alphanumerics, periods, underscores, hyphens, and parentheses. Cannot end with period." | |
| VALIDATION_FAILED=true | |
| elif [[ ${#INPUT_RESOURCE_GROUP_NAME} -gt 90 ]]; then | |
| echo "❌ ERROR: resource_group_name '$INPUT_RESOURCE_GROUP_NAME' exceeds 90 characters (length: ${#INPUT_RESOURCE_GROUP_NAME})" | |
| VALIDATION_FAILED=true | |
| else | |
| echo "✅ resource_group_name: '$INPUT_RESOURCE_GROUP_NAME' is valid" | |
| fi | |
| else | |
| echo "✅ resource_group_name: Not provided (will be auto-generated)" | |
| fi | |
| # Validate waf_enabled (boolean) | |
| WAF_ENABLED="${INPUT_WAF_ENABLED:-false}" | |
| if [[ "$WAF_ENABLED" != "true" && "$WAF_ENABLED" != "false" ]]; then | |
| echo "❌ ERROR: waf_enabled must be 'true' or 'false', got: '$WAF_ENABLED'" | |
| VALIDATION_FAILED=true | |
| else | |
| echo "✅ waf_enabled: '$WAF_ENABLED' is valid" | |
| fi | |
| # Validate EXP (boolean) | |
| EXP_ENABLED="${INPUT_EXP:-false}" | |
| if [[ "$EXP_ENABLED" != "true" && "$EXP_ENABLED" != "false" ]]; then | |
| echo "❌ ERROR: EXP must be 'true' or 'false', got: '$EXP_ENABLED'" | |
| VALIDATION_FAILED=true | |
| else | |
| echo "✅ EXP: '$EXP_ENABLED' is valid" | |
| fi | |
| # Validate build_docker_image (boolean) | |
| BUILD_DOCKER="${INPUT_BUILD_DOCKER_IMAGE:-false}" | |
| if [[ "$BUILD_DOCKER" != "true" && "$BUILD_DOCKER" != "false" ]]; then | |
| echo "❌ ERROR: build_docker_image must be 'true' or 'false', got: '$BUILD_DOCKER'" | |
| VALIDATION_FAILED=true | |
| else | |
| echo "✅ build_docker_image: '$BUILD_DOCKER' is valid" | |
| fi | |
| # Validate cleanup_resources (boolean) | |
| CLEANUP_RESOURCES="${INPUT_CLEANUP_RESOURCES:-false}" | |
| if [[ "$CLEANUP_RESOURCES" != "true" && "$CLEANUP_RESOURCES" != "false" ]]; then | |
| echo "❌ ERROR: cleanup_resources must be 'true' or 'false', got: '$CLEANUP_RESOURCES'" | |
| VALIDATION_FAILED=true | |
| else | |
| echo "✅ cleanup_resources: '$CLEANUP_RESOURCES' is valid" | |
| fi | |
| # Validate run_e2e_tests (specific allowed values) | |
| TEST_OPTION="${INPUT_RUN_E2E_TESTS:-GoldenPath-Testing}" | |
| if [[ "$TEST_OPTION" != "GoldenPath-Testing" && "$TEST_OPTION" != "Smoke-Testing" && "$TEST_OPTION" != "None" ]]; then | |
| echo "❌ ERROR: run_e2e_tests must be one of: GoldenPath-Testing, Smoke-Testing, None, got: '$TEST_OPTION'" | |
| VALIDATION_FAILED=true | |
| else | |
| echo "✅ run_e2e_tests: '$TEST_OPTION' is valid" | |
| fi | |
| # Validate AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID (optional, Azure Resource ID format) | |
| if [[ -n "$INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID" ]]; then | |
| 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 | |
| echo "❌ ERROR: AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID is invalid. Must be a valid Azure Resource ID format:" | |
| echo " /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}" | |
| echo " Got: '$INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID'" | |
| VALIDATION_FAILED=true | |
| else | |
| echo "✅ AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID: Valid Resource ID format" | |
| fi | |
| else | |
| echo "✅ AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID: Not provided (optional)" | |
| fi | |
| # Validate AZURE_EXISTING_AI_PROJECT_RESOURCE_ID (optional, Azure Resource ID format) | |
| if [[ -n "$INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID" ]]; then | |
| 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 | |
| echo "❌ ERROR: AZURE_EXISTING_AI_PROJECT_RESOURCE_ID is invalid. Must be a valid Azure Resource ID format:" | |
| echo " /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CognitiveServices/accounts/{accountName}/projects/{projectName}" | |
| echo " Got: '$INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID'" | |
| VALIDATION_FAILED=true | |
| else | |
| echo "✅ AZURE_EXISTING_AI_PROJECT_RESOURCE_ID: Valid Resource ID format" | |
| fi | |
| else | |
| echo "✅ AZURE_EXISTING_AI_PROJECT_RESOURCE_ID: Not provided (optional)" | |
| fi | |
| # Validate existing_webapp_url (optional, must start with https) | |
| if [[ -n "$INPUT_EXISTING_WEBAPP_URL" ]]; then | |
| if [[ ! "$INPUT_EXISTING_WEBAPP_URL" =~ ^https:// ]]; then | |
| echo "❌ ERROR: existing_webapp_url must start with 'https://', got: '$INPUT_EXISTING_WEBAPP_URL'" | |
| VALIDATION_FAILED=true | |
| else | |
| echo "✅ existing_webapp_url: '$INPUT_EXISTING_WEBAPP_URL' is valid" | |
| fi | |
| else | |
| echo "✅ existing_webapp_url: Not provided (will perform deployment)" | |
| fi | |
| # Fail workflow if any validation failed | |
| if [[ "$VALIDATION_FAILED" == "true" ]]; then | |
| echo "" | |
| echo "❌ Parameter validation failed. Please correct the errors above and try again." | |
| exit 1 | |
| fi | |
| echo "" | |
| echo "✅ All input parameters validated successfully!" | |
| # Output validated values | |
| echo "passed=true" >> $GITHUB_OUTPUT | |
| echo "azure_location=$LOCATION" >> $GITHUB_OUTPUT | |
| echo "resource_group_name=$INPUT_RESOURCE_GROUP_NAME" >> $GITHUB_OUTPUT | |
| echo "waf_enabled=$WAF_ENABLED" >> $GITHUB_OUTPUT | |
| echo "exp=$EXP_ENABLED" >> $GITHUB_OUTPUT | |
| echo "build_docker_image=$BUILD_DOCKER" >> $GITHUB_OUTPUT | |
| echo "cleanup_resources=$CLEANUP_RESOURCES" >> $GITHUB_OUTPUT | |
| echo "run_e2e_tests=$TEST_OPTION" >> $GITHUB_OUTPUT | |
| echo "azure_env_log_analytics_workspace_id=$INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID" >> $GITHUB_OUTPUT | |
| echo "azure_existing_ai_project_resource_id=$INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID" >> $GITHUB_OUTPUT | |
| echo "existing_webapp_url=$INPUT_EXISTING_WEBAPP_URL" >> $GITHUB_OUTPUT | |
| Run: | |
| needs: validate-inputs | |
| if: needs.validate-inputs.outputs.validation_passed == 'true' | |
| uses: ./.github/workflows/deploy-orchestrator.yml | |
| with: | |
| runner_os: ubuntu-latest | |
| azure_location: ${{ needs.validate-inputs.outputs.azure_location || 'australiaeast' }} | |
| resource_group_name: ${{ needs.validate-inputs.outputs.resource_group_name || '' }} | |
| waf_enabled: ${{ needs.validate-inputs.outputs.waf_enabled == 'true' }} | |
| EXP: ${{ needs.validate-inputs.outputs.exp == 'true' }} | |
| build_docker_image: ${{ needs.validate-inputs.outputs.build_docker_image == 'true' }} | |
| cleanup_resources: ${{ needs.validate-inputs.outputs.cleanup_resources == 'true' }} | |
| run_e2e_tests: ${{ needs.validate-inputs.outputs.run_e2e_tests || 'GoldenPath-Testing' }} | |
| AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID: ${{ needs.validate-inputs.outputs.azure_env_log_analytics_workspace_id || '' }} | |
| AZURE_EXISTING_AI_PROJECT_RESOURCE_ID: ${{ needs.validate-inputs.outputs.azure_existing_ai_project_resource_id || '' }} | |
| existing_webapp_url: ${{ needs.validate-inputs.outputs.existing_webapp_url || '' }} | |
| trigger_type: ${{ github.event_name }} | |
| secrets: inherit |