From 34df0662e4da5d7e02cfaf8fbd2b75725fb8d063 Mon Sep 17 00:00:00 2001
From: Vamshi-Microsoft
Date: Tue, 19 May 2026 12:22:08 +0530
Subject: [PATCH 1/2] Enhance email template, add RG owner tag, scalability
input
---
.github/workflows/deploy-orchestrator.yml | 22 +-
.github/workflows/deploy-v2.yml | 39 +-
.github/workflows/deploy-waf.yml | 15 +-
.github/workflows/deploy.yml | 11 +-
.github/workflows/job-deploy-linux.yml | 21 +
.github/workflows/job-deploy-windows.yml | 21 +
.github/workflows/job-deploy.yml | 31 +-
.github/workflows/job-send-notification.yml | 512 ++++++++++++++++----
8 files changed, 552 insertions(+), 120 deletions(-)
diff --git a/.github/workflows/deploy-orchestrator.yml b/.github/workflows/deploy-orchestrator.yml
index d61dcd6b6..4148def1a 100644
--- a/.github/workflows/deploy-orchestrator.yml
+++ b/.github/workflows/deploy-orchestrator.yml
@@ -8,7 +8,7 @@ on:
required: true
type: string
azure_location:
- description: 'Azure Location For Deployment'
+ description: 'Azure Region (Non-AI Services)'
required: false
default: 'australiaeast'
type: string
@@ -18,22 +18,27 @@ on:
default: ''
type: string
waf_enabled:
- description: 'Enable WAF'
+ description: 'Deploy WAF'
+ required: false
+ default: false
+ type: boolean
+ enable_scalability:
+ description: 'Enable Scalability features for WAF deployments (opt-in, defaults to false)'
required: false
default: false
type: boolean
EXP:
- description: 'Enable EXP'
+ description: 'Deploy EXP'
required: false
default: false
type: boolean
build_docker_image:
- description: 'Build And Push Docker Image (Optional)'
+ description: 'Build & Use Custom Images (Optional)'
required: false
default: false
type: boolean
cleanup_resources:
- description: 'Cleanup Deployed Resources'
+ description: 'Auto Delete RG'
required: false
default: false
type: boolean
@@ -43,17 +48,17 @@ on:
default: 'GoldenPath-Testing'
type: string
AZURE_ENV_EXISTING_LOG_ANALYTICS_WORKSPACE_RID:
- description: 'Log Analytics Workspace ID (Optional)'
+ description: 'Existing Log Analytics Workspace Resource ID (Optional)'
required: false
default: ''
type: string
AZURE_EXISTING_AIPROJECT_RESOURCE_ID:
- description: 'AI Project Resource ID (Optional)'
+ description: 'Existing AI Project Resource ID (Optional)'
required: false
default: ''
type: string
existing_webapp_url:
- description: 'Existing Container WebApp URL (Skips Deployment)'
+ description: 'Run Tests Against Existing RG (Provide Web App URL)'
required: false
default: ''
type: string
@@ -83,6 +88,7 @@ jobs:
azure_location: ${{ inputs.azure_location }}
resource_group_name: ${{ inputs.resource_group_name }}
waf_enabled: ${{ inputs.waf_enabled }}
+ enable_scalability: ${{ inputs.enable_scalability }}
EXP: ${{ inputs.EXP }}
build_docker_image: ${{ inputs.build_docker_image }}
existing_webapp_url: ${{ inputs.existing_webapp_url }}
diff --git a/.github/workflows/deploy-v2.yml b/.github/workflows/deploy-v2.yml
index 897914b59..2bdff5741 100644
--- a/.github/workflows/deploy-v2.yml
+++ b/.github/workflows/deploy-v2.yml
@@ -24,7 +24,7 @@ on:
- 'Local'
default: 'codespace'
azure_location:
- description: 'Azure Location For Deployment'
+ description: 'Azure Region (Non-AI Services)'
required: false
default: 'australiaeast'
type: choice
@@ -43,24 +43,30 @@ on:
default: ''
type: string
+ build_docker_image:
+ description: 'Build & Use Custom Images (Optional)'
+ required: false
+ default: false
+ type: boolean
+
waf_enabled:
- description: 'Enable WAF'
+ description: 'Deploy WAF'
required: false
default: false
type: boolean
- EXP:
- description: 'Enable EXP'
+ enable_scalability:
+ description: 'Enable Scalability (WAF only)'
required: false
default: false
type: boolean
- build_docker_image:
- description: 'Build & Push Docker Image (Optional)'
+ EXP:
+ description: 'Deploy EXP'
required: false
default: false
type: boolean
cleanup_resources:
- description: 'Cleanup Deployed Resources'
+ description: 'Auto Delete RG'
required: false
default: false
type: boolean
@@ -76,17 +82,17 @@ on:
- 'None'
AZURE_ENV_EXISTING_LOG_ANALYTICS_WORKSPACE_RID:
- description: 'Log Analytics Workspace ID (Optional)'
+ description: 'Existing Log Analytics Workspace Resource ID (Optional)'
required: false
default: ''
type: string
AZURE_EXISTING_AIPROJECT_RESOURCE_ID:
- description: 'AI Project Resource ID (Optional)'
+ description: 'Existing AI Project Resource ID (Optional)'
required: false
default: ''
type: string
existing_webapp_url:
- description: 'Existing WebApp URL (Skips Deployment)'
+ description: 'Run Tests Against Existing RG (Provide Web App URL)'
required: false
default: ''
type: string
@@ -103,6 +109,7 @@ jobs:
azure_location: ${{ steps.validate.outputs.azure_location }}
resource_group_name: ${{ steps.validate.outputs.resource_group_name }}
waf_enabled: ${{ steps.validate.outputs.waf_enabled }}
+ enable_scalability: ${{ steps.validate.outputs.enable_scalability }}
exp: ${{ steps.validate.outputs.exp }}
build_docker_image: ${{ steps.validate.outputs.build_docker_image }}
cleanup_resources: ${{ steps.validate.outputs.cleanup_resources }}
@@ -119,6 +126,7 @@ jobs:
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_ENABLE_SCALABILITY: ${{ github.event.inputs.enable_scalability }}
INPUT_EXP: ${{ github.event.inputs.EXP }}
INPUT_BUILD_DOCKER_IMAGE: ${{ github.event.inputs.build_docker_image }}
INPUT_CLEANUP_RESOURCES: ${{ github.event.inputs.cleanup_resources }}
@@ -178,6 +186,15 @@ jobs:
echo "✅ waf_enabled: '$WAF_ENABLED' is valid"
fi
+ # Validate enable_scalability (boolean, opt-in for WAF deployments)
+ ENABLE_SCALABILITY="${INPUT_ENABLE_SCALABILITY:-false}"
+ if [[ "$ENABLE_SCALABILITY" != "true" && "$ENABLE_SCALABILITY" != "false" ]]; then
+ echo "❌ ERROR: enable_scalability must be 'true' or 'false', got: '$ENABLE_SCALABILITY'"
+ VALIDATION_FAILED=true
+ else
+ echo "✅ enable_scalability: '$ENABLE_SCALABILITY' is valid"
+ fi
+
# Validate EXP (boolean)
EXP_ENABLED="${INPUT_EXP:-false}"
if [[ "$EXP_ENABLED" != "true" && "$EXP_ENABLED" != "false" ]]; then
@@ -270,6 +287,7 @@ jobs:
echo "azure_location=$LOCATION" >> $GITHUB_OUTPUT
echo "resource_group_name=$INPUT_RESOURCE_GROUP_NAME" >> $GITHUB_OUTPUT
echo "waf_enabled=$WAF_ENABLED" >> $GITHUB_OUTPUT
+ echo "enable_scalability=$ENABLE_SCALABILITY" >> $GITHUB_OUTPUT
echo "exp=$EXP_ENABLED" >> $GITHUB_OUTPUT
echo "build_docker_image=$BUILD_DOCKER" >> $GITHUB_OUTPUT
echo "cleanup_resources=$CLEANUP_RESOURCES" >> $GITHUB_OUTPUT
@@ -287,6 +305,7 @@ jobs:
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' }}
+ enable_scalability: ${{ needs.validate-inputs.outputs.enable_scalability == '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' }}
diff --git a/.github/workflows/deploy-waf.yml b/.github/workflows/deploy-waf.yml
index 49729e484..ace2f4dc2 100644
--- a/.github/workflows/deploy-waf.yml
+++ b/.github/workflows/deploy-waf.yml
@@ -94,14 +94,19 @@ jobs:
- name: Check and Create Resource Group
id: check_create_rg
run: |
- set -e
- echo "Checking if resource group exists..."
+ set -e
+ OWNER_TAG_VALUE="${{ github.actor }}"
+ echo "🔍 Checking if resource group '${{ env.RESOURCE_GROUP_NAME }}' exists..."
rg_exists=$(az group exists --name ${{ env.RESOURCE_GROUP_NAME }})
if [ "$rg_exists" = "false" ]; then
- echo "Resource group does not exist. Creating..."
- az group create --name ${{ env.RESOURCE_GROUP_NAME }} --location ${{ env.AZURE_LOCATION }} || { echo "Error creating resource group"; exit 1; }
+ echo "📦 Resource group does not exist. Creating new resource group '${{ env.RESOURCE_GROUP_NAME }}' in location '${{ env.AZURE_LOCATION }}'..."
+ echo "🏷️ Adding Owner tag: Owner=${OWNER_TAG_VALUE}"
+ az group create --name ${{ env.RESOURCE_GROUP_NAME }} --location ${{ env.AZURE_LOCATION }} --tags "Owner=${OWNER_TAG_VALUE}" || { echo "❌ Error creating resource group"; exit 1; }
+ echo "✅ Resource group '${{ env.RESOURCE_GROUP_NAME }}' created successfully."
else
- echo "Resource group already exists."
+ echo "✅ Resource group '${{ env.RESOURCE_GROUP_NAME }}' already exists."
+ echo "🏷️ Merging Owner tag on existing resource group: Owner=${OWNER_TAG_VALUE}"
+ az group update --name "${{ env.RESOURCE_GROUP_NAME }}" --set tags.Owner="${OWNER_TAG_VALUE}" --output none || echo "⚠️ Warning: failed to update Owner tag on existing resource group '${{ env.RESOURCE_GROUP_NAME }}'."
fi
- name: Generate Unique Solution Prefix
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index cd1ac2c2f..1e0bd7a2a 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -101,9 +101,18 @@ jobs:
id: check_create_rg
run: |
set -e
+ OWNER_TAG_VALUE="${{ github.actor }}"
+ echo "🔍 Checking if resource group '${{ env.RESOURCE_GROUP_NAME }}' exists..."
rg_exists=$(az group exists --name ${{ env.RESOURCE_GROUP_NAME }})
if [ "$rg_exists" = "false" ]; then
- az group create --name ${{ env.RESOURCE_GROUP_NAME }} --location ${{ env.AZURE_LOCATION }}
+ echo "📦 Resource group does not exist. Creating new resource group '${{ env.RESOURCE_GROUP_NAME }}' in location '${{ env.AZURE_LOCATION }}'..."
+ echo "🏷️ Adding Owner tag: Owner=${OWNER_TAG_VALUE}"
+ az group create --name ${{ env.RESOURCE_GROUP_NAME }} --location ${{ env.AZURE_LOCATION }} --tags "Owner=${OWNER_TAG_VALUE}" || { echo "❌ Error creating resource group"; exit 1; }
+ echo "✅ Resource group '${{ env.RESOURCE_GROUP_NAME }}' created successfully."
+ else
+ echo "✅ Resource group '${{ env.RESOURCE_GROUP_NAME }}' already exists. Deploying to existing resource group."
+ echo "🏷️ Merging Owner tag on existing resource group: Owner=${OWNER_TAG_VALUE}"
+ az group update --name "${{ env.RESOURCE_GROUP_NAME }}" --set tags.Owner="${OWNER_TAG_VALUE}" --output none || echo "⚠️ Warning: failed to update Owner tag on existing resource group '${{ env.RESOURCE_GROUP_NAME }}'."
fi
echo "RESOURCE_GROUP_NAME=${{ env.RESOURCE_GROUP_NAME }}" >> $GITHUB_OUTPUT
diff --git a/.github/workflows/job-deploy-linux.yml b/.github/workflows/job-deploy-linux.yml
index e8c7c9d70..ad5cfb678 100644
--- a/.github/workflows/job-deploy-linux.yml
+++ b/.github/workflows/job-deploy-linux.yml
@@ -28,6 +28,11 @@ on:
required: false
type: string
default: 'false'
+ ENABLE_SCALABILITY:
+ description: 'Enable Scalability features for WAF deployments (opt-in)'
+ required: false
+ type: string
+ default: 'false'
AZURE_ENV_EXISTING_LOG_ANALYTICS_WORKSPACE_RID:
required: false
type: string
@@ -192,10 +197,26 @@ jobs:
shell: bash
env:
INPUT_WAF_ENABLED: ${{ inputs.WAF_ENABLED }}
+ INPUT_ENABLE_SCALABILITY: ${{ inputs.ENABLE_SCALABILITY }}
run: |
+ set -euo pipefail
if [[ "$INPUT_WAF_ENABLED" == "true" ]]; then
cp infra/main.waf.parameters.json infra/main.parameters.json
echo "✅ Successfully copied WAF parameters to main parameters file"
+ SCALABILITY_VALUE="${INPUT_ENABLE_SCALABILITY:-false}"
+ if [[ "$SCALABILITY_VALUE" != "true" && "$SCALABILITY_VALUE" != "false" ]]; then
+ echo "❌ ERROR: ENABLE_SCALABILITY must be 'true' or 'false', got: '$SCALABILITY_VALUE'"
+ exit 1
+ fi
+ echo "🔧 Setting enableScalability=${SCALABILITY_VALUE}"
+ tmpfile=$(mktemp)
+ if ! jq --argjson v "$SCALABILITY_VALUE" '.parameters.enableScalability.value = $v' infra/main.parameters.json > "$tmpfile"; then
+ echo "❌ ERROR: jq failed to update enableScalability in infra/main.parameters.json"
+ rm -f "$tmpfile"
+ exit 1
+ fi
+ mv "$tmpfile" infra/main.parameters.json
+ echo "✅ enableScalability set to ${SCALABILITY_VALUE}"
else
echo "🔧 Configuring Non-WAF deployment - using default main.parameters.json..."
fi
diff --git a/.github/workflows/job-deploy-windows.yml b/.github/workflows/job-deploy-windows.yml
index 09120b68f..a6e9665c1 100644
--- a/.github/workflows/job-deploy-windows.yml
+++ b/.github/workflows/job-deploy-windows.yml
@@ -28,6 +28,11 @@ on:
required: false
type: string
default: 'false'
+ ENABLE_SCALABILITY:
+ description: 'Enable Scalability features for WAF deployments (opt-in)'
+ required: false
+ type: string
+ default: 'false'
AZURE_ENV_EXISTING_LOG_ANALYTICS_WORKSPACE_RID:
required: false
type: string
@@ -191,10 +196,26 @@ jobs:
shell: bash
env:
INPUT_WAF_ENABLED: ${{ inputs.WAF_ENABLED }}
+ INPUT_ENABLE_SCALABILITY: ${{ inputs.ENABLE_SCALABILITY }}
run: |
+ set -euo pipefail
if [[ "$INPUT_WAF_ENABLED" == "true" ]]; then
cp infra/main.waf.parameters.json infra/main.parameters.json
echo "✅ Successfully copied WAF parameters to main parameters file"
+ SCALABILITY_VALUE="${INPUT_ENABLE_SCALABILITY:-false}"
+ if [[ "$SCALABILITY_VALUE" != "true" && "$SCALABILITY_VALUE" != "false" ]]; then
+ echo "❌ ERROR: ENABLE_SCALABILITY must be 'true' or 'false', got: '$SCALABILITY_VALUE'"
+ exit 1
+ fi
+ echo "🔧 Setting enableScalability=${SCALABILITY_VALUE}"
+ tmpfile=$(mktemp)
+ if ! jq --argjson v "$SCALABILITY_VALUE" '.parameters.enableScalability.value = $v' infra/main.parameters.json > "$tmpfile"; then
+ echo "❌ ERROR: jq failed to update enableScalability in infra/main.parameters.json"
+ rm -f "$tmpfile"
+ exit 1
+ fi
+ mv "$tmpfile" infra/main.parameters.json
+ echo "✅ enableScalability set to ${SCALABILITY_VALUE}"
else
echo "🔧 Configuring Non-WAF deployment - using default main.parameters.json..."
fi
diff --git a/.github/workflows/job-deploy.yml b/.github/workflows/job-deploy.yml
index 85c633009..a5af4831a 100644
--- a/.github/workflows/job-deploy.yml
+++ b/.github/workflows/job-deploy.yml
@@ -12,7 +12,7 @@ on:
required: true
type: string
azure_location:
- description: 'Azure Location For Deployment'
+ description: 'Azure Region (Non-AI Services)'
required: false
default: 'australiaeast'
type: string
@@ -22,22 +22,27 @@ on:
default: ''
type: string
waf_enabled:
- description: 'Enable WAF'
+ description: 'Deploy WAF'
+ required: false
+ default: false
+ type: boolean
+ enable_scalability:
+ description: 'Enable Scalability features for WAF deployments (opt-in, defaults to false)'
required: false
default: false
type: boolean
EXP:
- description: 'Enable EXP'
+ description: 'Deploy EXP'
required: false
default: false
type: boolean
build_docker_image:
- description: 'Build And Push Docker Image (Optional)'
+ description: 'Build & Use Custom Images (Optional)'
required: false
default: false
type: boolean
cleanup_resources:
- description: 'Cleanup Deployed Resources'
+ description: 'Auto Delete RG'
required: false
default: false
type: boolean
@@ -47,17 +52,17 @@ on:
default: 'GoldenPath-Testing'
type: string
existing_webapp_url:
- description: 'Existing Container WebApp URL (Skips Deployment)'
+ description: 'Run Tests Against Existing RG (Provide Web App URL)'
required: false
default: ''
type: string
AZURE_ENV_EXISTING_LOG_ANALYTICS_WORKSPACE_RID:
- description: 'Log Analytics Workspace ID (Optional)'
+ description: 'Existing Log Analytics Workspace Resource ID (Optional)'
required: false
default: ''
type: string
AZURE_EXISTING_AIPROJECT_RESOURCE_ID:
- description: 'AI Project Resource ID (Optional)'
+ description: 'Existing AI Project Resource ID (Optional)'
required: false
default: ''
type: string
@@ -377,15 +382,19 @@ jobs:
id: check_create_rg
shell: bash
run: |
- set -e
+ set -e
+ OWNER_TAG_VALUE="${{ github.actor }}"
echo "🔍 Checking if resource group '$RESOURCE_GROUP_NAME' exists..."
rg_exists=$(az group exists --name $RESOURCE_GROUP_NAME)
if [ "$rg_exists" = "false" ]; then
echo "📦 Resource group does not exist. Creating new resource group '$RESOURCE_GROUP_NAME' in location '$AZURE_LOCATION'..."
- az group create --name $RESOURCE_GROUP_NAME --location $AZURE_LOCATION --tags ${{ env.RG_TAGS }} || { echo "❌ Error creating resource group"; exit 1; }
+ echo "🏷️ Adding Owner tag: Owner=${OWNER_TAG_VALUE}"
+ az group create --name $RESOURCE_GROUP_NAME --location $AZURE_LOCATION --tags ${{ env.RG_TAGS }} "Owner=${OWNER_TAG_VALUE}" || { echo "❌ Error creating resource group"; exit 1; }
echo "✅ Resource group '$RESOURCE_GROUP_NAME' created successfully."
else
echo "✅ Resource group '$RESOURCE_GROUP_NAME' already exists. Deploying to existing resource group."
+ echo "🏷️ Adding Owner tag on existing resource group: Owner=${OWNER_TAG_VALUE}"
+ az group update --name "$RESOURCE_GROUP_NAME" --set tags.Owner="${OWNER_TAG_VALUE}" --output none || echo "⚠️ Warning: failed to update Owner tag on existing resource group '$RESOURCE_GROUP_NAME'."
fi
echo "RESOURCE_GROUP_NAME=$RESOURCE_GROUP_NAME" >> $GITHUB_OUTPUT
echo "RESOURCE_GROUP_NAME=$RESOURCE_GROUP_NAME" >> $GITHUB_ENV
@@ -502,6 +511,7 @@ jobs:
BUILD_DOCKER_IMAGE: ${{ inputs.build_docker_image || 'false' }}
EXP: ${{ needs.azure-setup.outputs.EXP_ENABLED }}
WAF_ENABLED: ${{ inputs.waf_enabled == true && 'true' || 'false' }}
+ ENABLE_SCALABILITY: ${{ inputs.enable_scalability == true && 'true' || 'false' }}
AZURE_ENV_EXISTING_LOG_ANALYTICS_WORKSPACE_RID: ${{ inputs.AZURE_ENV_EXISTING_LOG_ANALYTICS_WORKSPACE_RID }}
AZURE_EXISTING_AIPROJECT_RESOURCE_ID: ${{ inputs.AZURE_EXISTING_AIPROJECT_RESOURCE_ID }}
secrets: inherit
@@ -520,6 +530,7 @@ jobs:
BUILD_DOCKER_IMAGE: ${{ inputs.build_docker_image || 'false' }}
EXP: ${{ needs.azure-setup.outputs.EXP_ENABLED }}
WAF_ENABLED: ${{ inputs.waf_enabled == true && 'true' || 'false' }}
+ ENABLE_SCALABILITY: ${{ inputs.enable_scalability == true && 'true' || 'false' }}
AZURE_ENV_EXISTING_LOG_ANALYTICS_WORKSPACE_RID: ${{ inputs.AZURE_ENV_EXISTING_LOG_ANALYTICS_WORKSPACE_RID }}
AZURE_EXISTING_AIPROJECT_RESOURCE_ID: ${{ inputs.AZURE_EXISTING_AIPROJECT_RESOURCE_ID }}
secrets: inherit
diff --git a/.github/workflows/job-send-notification.yml b/.github/workflows/job-send-notification.yml
index 836639e25..2bef97813 100644
--- a/.github/workflows/job-send-notification.yml
+++ b/.github/workflows/job-send-notification.yml
@@ -99,17 +99,25 @@ jobs:
echo "TEST_SUITE_NAME=$TEST_SUITE_NAME" >> $GITHUB_OUTPUT
echo "Test Suite: $TEST_SUITE_NAME"
- - name: Determine Cleanup Status
+ - name: Determine Cleanup Pill
id: cleanup
shell: bash
env:
CLEANUP_RESULT: ${{ inputs.cleanup_result }}
run: |
+ PILL_BASE="display:inline-block; min-width:70px; text-align:center; padding:4px 12px; border-radius:20px; font-size:12px; font-weight:600; line-height:1.4;"
case "$CLEANUP_RESULT" in
- success) echo "CLEANUP_STATUS=✅ SUCCESS" >> $GITHUB_OUTPUT ;;
- failure) echo "CLEANUP_STATUS=❌ FAILED (Needs Manual Cleanup)" >> $GITHUB_OUTPUT ;;
- *) echo "CLEANUP_STATUS=⏭️ SKIPPED (Needs Manual Cleanup)" >> $GITHUB_OUTPUT ;;
+ success)
+ CLEANUP_PILL="✅ SUCCESS"
+ ;;
+ failure)
+ CLEANUP_PILL="❌ FAILED"
+ ;;
+ *)
+ CLEANUP_PILL="⏭️ SKIPPED"
+ ;;
esac
+ echo "CLEANUP_PILL=$CLEANUP_PILL" >> $GITHUB_OUTPUT
- name: Determine Configuration Label
id: config
@@ -122,6 +130,9 @@ jobs:
EXP_LABEL=$( [ "$EXP" = "true" ] && echo "EXP" || echo "Non-EXP" )
echo "CONFIG_LABEL=${WAF_LABEL} + ${EXP_LABEL}" >> $GITHUB_OUTPUT
+ # ------------------------------------------------------------------
+ # Quota failure
+ # ------------------------------------------------------------------
- name: Send Quota Failure Notification
if: inputs.deploy_result == 'failure' && inputs.QUOTA_FAILED == 'true'
shell: bash
@@ -130,51 +141,156 @@ jobs:
GITHUB_RUN_ID: ${{ github.run_id }}
ACCELERATOR_NAME: ${{ env.accelerator_name }}
LOGICAPP_URL: ${{ secrets.EMAILNOTIFICATION_LOGICAPP_URL_TA }}
- CLEANUP_STATUS: ${{ steps.cleanup.outputs.CLEANUP_STATUS }}
+ CLEANUP_PILL: ${{ steps.cleanup.outputs.CLEANUP_PILL }}
CONFIG_LABEL: ${{ steps.config.outputs.CONFIG_LABEL }}
run: |
RUN_URL="https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
- EMAIL_BODY=$(cat <Dear Team,
We would like to inform you that the ${ACCELERATOR_NAME} deployment has failed due to insufficient quota.
Status Summary:
| Stage | Status |
|---|
| Deployment | ❌ FAILED (Insufficient Quota) |
| E2E Tests | ⏭️ SKIPPED |
| Cleanup | ${CLEANUP_STATUS} |
Configuration: ${CONFIG_LABEL}
Run URL: ${RUN_URL}
Please resolve the quota issue and retry the deployment.
Best regards,
Your Automation Team
",
- "subject": "❌[CI/CD-Automation] [${ACCELERATOR_NAME}] Insufficient Quota"
- }
- EOF
+ PILL_BASE="display:inline-block; min-width:70px; text-align:center; padding:4px 12px; border-radius:20px; font-size:12px; font-weight:600; line-height:1.4;"
+ DEPLOY_PILL="❌ FAILED"
+ E2E_PILL="⏭️ SKIPPED"
+
+ BODY_HTML=$(cat <
+
+
+
+
+ Pipeline Failed — Insufficient Quota
+ ${ACCELERATOR_NAME} Accelerator • CI/CD Automation |
+
+ ${CONFIG_LABEL}
+ |
+
+ |
+ |
+ Dear Team, The ${ACCELERATOR_NAME} deployment has failed due to insufficient quota.
+
+ Status Summary
+
+ | Deployment | ${DEPLOY_PILL} |
+ | E2E Tests | ${E2E_PILL} |
+ | Cleanup | ${CLEANUP_PILL} |
+
+
+
+ Please resolve the quota issue and retry the deployment.
+
+ Deployment Details
+
+ | Triggered By |
+ ${{ github.actor }} |
+ | Branch |
+ ${{ env.BRANCH_NAME }} |
+
+
+ |
+
+
+ | CI/CD Automation Pipeline |
+ ${ACCELERATOR_NAME} Accelerator |
+
+ |
+
+ |
+
+ HTML
)
+ BODY_JSON=$(printf '%s' "$BODY_HTML" | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))')
+ PAYLOAD="{\"subject\":\"\u274C[CI/CD-Automation] [${ACCELERATOR_NAME}] Insufficient Quota\",\"body\":${BODY_JSON}}"
curl -X POST "${LOGICAPP_URL}" \
-H "Content-Type: application/json" \
- -d "$EMAIL_BODY" || echo "Failed to send quota failure notification"
+ -d "$PAYLOAD" || echo "Failed to send quota failure notification"
+ # ------------------------------------------------------------------
+ # Deployment failure (non-quota)
+ # ------------------------------------------------------------------
- name: Send Deployment Failure Notification
if: inputs.deploy_result == 'failure' && inputs.QUOTA_FAILED != 'true'
shell: bash
env:
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_RUN_ID: ${{ github.run_id }}
INPUT_RESOURCE_GROUP_NAME: ${{ inputs.RESOURCE_GROUP_NAME }}
ACCELERATOR_NAME: ${{ env.accelerator_name }}
LOGICAPP_URL: ${{ secrets.EMAILNOTIFICATION_LOGICAPP_URL_TA }}
CONFIG_LABEL: ${{ steps.config.outputs.CONFIG_LABEL }}
- CLEANUP_STATUS: ${{ steps.cleanup.outputs.CLEANUP_STATUS }}
+ CLEANUP_PILL: ${{ steps.cleanup.outputs.CLEANUP_PILL }}
run: |
- RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
+ RUN_URL="https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
RESOURCE_GROUP="$INPUT_RESOURCE_GROUP_NAME"
-
- EMAIL_BODY=$(cat <Dear Team,We would like to inform you that the ${ACCELERATOR_NAME} deployment has failed.
Status Summary:
| Stage | Status |
|---|
| Deployment | ❌ FAILED (Deployment Issue) |
| E2E Tests | ⏭️ SKIPPED |
| Cleanup | ${CLEANUP_STATUS} |
Deployment Details:
• Resource Group: ${RESOURCE_GROUP}
Configuration: ${CONFIG_LABEL}
Run URL: ${RUN_URL}
Please investigate the deployment failure at your earliest convenience.
Best regards,
Your Automation Team
",
- "subject": "❌[CI/CD-Automation] [${ACCELERATOR_NAME}] Deployment-Failed"
- }
- EOF
+ PILL_BASE="display:inline-block; min-width:70px; text-align:center; padding:4px 12px; border-radius:20px; font-size:12px; font-weight:600; line-height:1.4;"
+ DEPLOY_PILL="❌ FAILED"
+ E2E_PILL="⏭️ SKIPPED"
+
+ BODY_HTML=$(cat <
+
+
+
+
+ Pipeline Failed
+ ${ACCELERATOR_NAME} Accelerator • CI/CD Automation |
+
+ ${CONFIG_LABEL}
+ |
+
+ |
+ |
+ Dear Team, The ${ACCELERATOR_NAME} deployment has failed. Please investigate at your earliest convenience.
+
+ Status Summary
+
+ | Deployment | ${DEPLOY_PILL} |
+ | E2E Tests | ${E2E_PILL} |
+ | Cleanup | ${CLEANUP_PILL} |
+
+
+
+ Please investigate the deployment failure at your earliest convenience.
+
+ Deployment Details
+
+ | Resource Group |
+ ${RESOURCE_GROUP} |
+ | Triggered By |
+ ${{ github.actor }} |
+ | Branch |
+ ${{ env.BRANCH_NAME }} |
+
+
+ |
+
+
+ | CI/CD Automation Pipeline |
+ ${ACCELERATOR_NAME} Accelerator |
+
+ |
+
+ |
+
+ HTML
)
-
+ BODY_JSON=$(printf '%s' "$BODY_HTML" | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))')
+ PAYLOAD="{\"subject\":\"\u274C[CI/CD-Automation] [${ACCELERATOR_NAME}] Deployment-Failed\",\"body\":${BODY_JSON}}"
+
curl -X POST "${LOGICAPP_URL}" \
-H "Content-Type: application/json" \
- -d "$EMAIL_BODY" || echo "Failed to send deployment failure notification"
+ -d "$PAYLOAD" || echo "Failed to send deployment failure notification"
+ # ------------------------------------------------------------------
+ # Success (deploy + optional E2E)
+ # ------------------------------------------------------------------
- name: Send Success Notification
if: inputs.deploy_result == 'success' && (inputs.e2e_test_result == 'skipped' || inputs.TEST_SUCCESS == 'true')
shell: bash
env:
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_RUN_ID: ${{ github.run_id }}
INPUT_CONTAINER_WEB_APPURL: ${{ inputs.CONTAINER_WEB_APPURL }}
INPUT_EXISTING_WEBAPP_URL: ${{ inputs.existing_webapp_url }}
INPUT_RESOURCE_GROUP_NAME: ${{ inputs.RESOURCE_GROUP_NAME }}
@@ -182,41 +298,91 @@ jobs:
INPUT_E2E_TEST_RESULT: ${{ inputs.e2e_test_result }}
ACCELERATOR_NAME: ${{ env.accelerator_name }}
LOGICAPP_URL: ${{ secrets.EMAILNOTIFICATION_LOGICAPP_URL_TA }}
- GITHUB_REPOSITORY: ${{ github.repository }}
- GITHUB_RUN_ID: ${{ github.run_id }}
CONFIG_LABEL: ${{ steps.config.outputs.CONFIG_LABEL }}
- CLEANUP_STATUS: ${{ steps.cleanup.outputs.CLEANUP_STATUS }}
- RUN_E2E_TESTS: ${{ env.RUN_E2E_TESTS }}
+ CLEANUP_PILL: ${{ steps.cleanup.outputs.CLEANUP_PILL }}
TEST_SUITE_NAME: ${{ steps.test_suite.outputs.TEST_SUITE_NAME }}
-
run: |
+ # HTML-escape values that get embedded into the email template to avoid HTML/attribute injection from workflow inputs.
+ html_escape() {
+ printf '%s' "$1" | sed -e 's/&/\&/g' -e 's/\</g' -e 's/>/\>/g' -e 's/"/\"/g' -e "s/'/\'/g"
+ }
RUN_URL="https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
- WEBAPP_URL="${INPUT_CONTAINER_WEB_APPURL:-$INPUT_EXISTING_WEBAPP_URL}"
- RESOURCE_GROUP="$INPUT_RESOURCE_GROUP_NAME"
- TEST_REPORT_URL="$INPUT_TEST_REPORT_URL"
-
+ WEBAPP_URL="$(html_escape "${INPUT_CONTAINER_WEB_APPURL:-$INPUT_EXISTING_WEBAPP_URL}")"
+ RESOURCE_GROUP="$(html_escape "$INPUT_RESOURCE_GROUP_NAME")"
+ TEST_REPORT_URL="$(html_escape "$INPUT_TEST_REPORT_URL")"
+ PILL_BASE="display:inline-block; min-width:70px; text-align:center; padding:4px 12px; border-radius:20px; font-size:12px; font-weight:600; line-height:1.4;"
+ DEPLOY_PILL="✅ SUCCESS"
+
if [ "$INPUT_E2E_TEST_RESULT" = "skipped" ]; then
- EMAIL_BODY=$(cat <Dear Team,We would like to inform you that the ${ACCELERATOR_NAME} deployment has completed successfully.
Status Summary:
| Stage | Status |
|---|
| Deployment | ✅ SUCCESS |
| E2E Tests | ⏭️ SKIPPED |
| Cleanup | ${CLEANUP_STATUS} |
Deployment Details:
• Resource Group: ${RESOURCE_GROUP}
• Web App URL: ${WEBAPP_URL}
Configuration: ${CONFIG_LABEL}
Run URL: ${RUN_URL}
Best regards,
Your Automation Team
",
- "subject": "✅[CI/CD-Automation] [${ACCELERATOR_NAME}] Success"
- }
- EOF
- )
+ E2E_PILL="⏭️ SKIPPED"
+ INTRO="The ${ACCELERATOR_NAME} deployment has completed successfully."
+ TEST_DETAIL_ROWS=""
else
- EMAIL_BODY=$(cat <Dear Team,We would like to inform you that the ${ACCELERATOR_NAME} deployment and test automation has completed successfully.
Status Summary:
| Stage | Status |
|---|
| Deployment | ✅ SUCCESS |
| E2E Tests | ✅ SUCCESS |
| Cleanup | ${CLEANUP_STATUS} |
Deployment Details:
• Resource Group: ${RESOURCE_GROUP}
• Web App URL: ${WEBAPP_URL}
• Test Suite: ${TEST_SUITE_NAME}
• Test Report: View Report
Configuration: ${CONFIG_LABEL}
Run URL: ${RUN_URL}
Best regards,
Your Automation Team
",
- "subject": "✅[CI/CD-Automation] [${ACCELERATOR_NAME}] Success"
- }
- EOF
- )
+ E2E_PILL="✅ SUCCESS"
+ INTRO="The ${ACCELERATOR_NAME} deployment and test automation has completed successfully."
+ TEST_DETAIL_ROWS="| Test Suite | ${TEST_SUITE_NAME} |
| Test Report | 📄 View Report |
"
fi
-
+
+ BODY_HTML=$(cat <
+
+
+
+
+ Pipeline Succeeded
+ ${ACCELERATOR_NAME} Accelerator • CI/CD Automation |
+
+ ${CONFIG_LABEL}
+ |
+
+ |
+ |
+ Dear Team, ${INTRO}
+
+ Status Summary
+
+ | Deployment | ${DEPLOY_PILL} |
+ | E2E Tests | ${E2E_PILL} |
+ | Cleanup | ${CLEANUP_PILL} |
+
+
+ Deployment Details
+
+ | Resource Group |
+ ${RESOURCE_GROUP} |
+ | Web App URL |
+ ${WEBAPP_URL} |
+ | Triggered By |
+ ${{ github.actor }} |
+ | Branch |
+ ${{ env.BRANCH_NAME }} |
+ ${TEST_DETAIL_ROWS}
+
+
+ |
+
+
+ | CI/CD Automation Pipeline |
+ ${ACCELERATOR_NAME} Accelerator |
+
+ |
+
+ |
+
+ HTML
+ )
+ BODY_JSON=$(printf '%s' "$BODY_HTML" | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))')
+ PAYLOAD="{\"subject\":\"\u2705[CI/CD-Automation] [${ACCELERATOR_NAME}] Success\",\"body\":${BODY_JSON}}"
+
curl -X POST "${LOGICAPP_URL}" \
-H "Content-Type: application/json" \
- -d "$EMAIL_BODY" || echo "Failed to send success notification"
+ -d "$PAYLOAD" || echo "Failed to send success notification"
+ # ------------------------------------------------------------------
+ # E2E test failure (deploy succeeded)
+ # ------------------------------------------------------------------
- name: Send Test Failure Notification
if: inputs.deploy_result == 'success' && inputs.e2e_test_result != 'skipped' && inputs.TEST_SUCCESS != 'true'
shell: bash
@@ -226,31 +392,88 @@ jobs:
INPUT_CONTAINER_WEB_APPURL: ${{ inputs.CONTAINER_WEB_APPURL }}
INPUT_EXISTING_WEBAPP_URL: ${{ inputs.existing_webapp_url }}
INPUT_RESOURCE_GROUP_NAME: ${{ inputs.RESOURCE_GROUP_NAME }}
+ INPUT_TEST_REPORT_URL: ${{ inputs.TEST_REPORT_URL }}
ACCELERATOR_NAME: ${{ env.accelerator_name }}
LOGICAPP_URL: ${{ secrets.EMAILNOTIFICATION_LOGICAPP_URL_TA }}
- CLEANUP_STATUS: ${{ steps.cleanup.outputs.CLEANUP_STATUS }}
+ CLEANUP_PILL: ${{ steps.cleanup.outputs.CLEANUP_PILL }}
CONFIG_LABEL: ${{ steps.config.outputs.CONFIG_LABEL }}
- RUN_E2E_TESTS: ${{ env.RUN_E2E_TESTS }}
TEST_SUITE_NAME: ${{ steps.test_suite.outputs.TEST_SUITE_NAME }}
- INPUT_TEST_REPORT_URL: ${{ inputs.TEST_REPORT_URL }}
run: |
- RUN_URL="https://github.com/${{ env.GITHUB_REPOSITORY }}/actions/runs/${{ env.GITHUB_RUN_ID }}"
- TEST_REPORT_URL="$INPUT_TEST_REPORT_URL"
- WEBAPP_URL="${INPUT_CONTAINER_WEB_APPURL:-$INPUT_EXISTING_WEBAPP_URL}"
- RESOURCE_GROUP="$INPUT_RESOURCE_GROUP_NAME"
-
- EMAIL_BODY=$(cat <Dear Team,We would like to inform you that ${ACCELERATOR_NAME} test automation has failed.
Status Summary:
| Stage | Status |
|---|
| Deployment | ✅ SUCCESS |
| E2E Tests | ❌ FAILED |
| Cleanup | ${CLEANUP_STATUS} |
Deployment Details:
• Resource Group: ${RESOURCE_GROUP}
• Web App URL: ${WEBAPP_URL}
• Test Suite: ${TEST_SUITE_NAME}
• Test Report: View Report
Configuration: ${CONFIG_LABEL}
Run URL: ${RUN_URL}
Please investigate the matter at your earliest convenience.
Best regards,
Your Automation Team
",
- "subject": "❌[CI/CD-Automation] [${ACCELERATOR_NAME}] E2E Test-Failed"
+ # HTML-escape values that get embedded into the email template to avoid HTML/attribute injection from workflow inputs.
+ html_escape() {
+ printf '%s' "$1" | sed -e 's/&/\&/g' -e 's/\</g' -e 's/>/\>/g' -e 's/"/\"/g' -e "s/'/\'/g"
}
- EOF
+ RUN_URL="https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
+ WEBAPP_URL="$(html_escape "${INPUT_CONTAINER_WEB_APPURL:-$INPUT_EXISTING_WEBAPP_URL}")"
+ RESOURCE_GROUP="$(html_escape "$INPUT_RESOURCE_GROUP_NAME")"
+ TEST_REPORT_URL="$(html_escape "$INPUT_TEST_REPORT_URL")"
+ PILL_BASE="display:inline-block; min-width:70px; text-align:center; padding:4px 12px; border-radius:20px; font-size:12px; font-weight:600; line-height:1.4;"
+ DEPLOY_PILL="✅ SUCCESS"
+ E2E_PILL="❌ FAILED"
+
+ BODY_HTML=$(cat <
+
+
+
+
+ E2E Tests Failed
+ ${ACCELERATOR_NAME} Accelerator • CI/CD Automation |
+
+ ${CONFIG_LABEL}
+ |
+
+ |
+ |
+ Dear Team, The ${ACCELERATOR_NAME} test automation has failed. Please investigate at your earliest convenience.
+
+ Status Summary
+
+ | Deployment | ${DEPLOY_PILL} |
+ | E2E Tests | ${E2E_PILL} |
+ | Cleanup | ${CLEANUP_PILL} |
+
+
+ Deployment Details
+
+ | Resource Group |
+ ${RESOURCE_GROUP} |
+ | Web App URL |
+ ${WEBAPP_URL} |
+ | Triggered By |
+ ${{ github.actor }} |
+ | Branch |
+ ${{ env.BRANCH_NAME }} |
+ | Test Suite |
+ ${TEST_SUITE_NAME} |
+ | Test Report |
+ 📄 View Report |
+
+
+ |
+
+
+ | CI/CD Automation Pipeline |
+ ${ACCELERATOR_NAME} Accelerator |
+
+ |
+
+ |
+
+ HTML
)
+ BODY_JSON=$(printf '%s' "$BODY_HTML" | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))')
+ PAYLOAD="{\"subject\":\"\u274C[CI/CD-Automation] [${ACCELERATOR_NAME}] E2E Test-Failed\",\"body\":${BODY_JSON}}"
curl -X POST "${LOGICAPP_URL}" \
-H "Content-Type: application/json" \
- -d "$EMAIL_BODY" || echo "Failed to send test failure notification"
+ -d "$PAYLOAD" || echo "Failed to send test failure notification"
+ # ------------------------------------------------------------------
+ # Existing URL: success
+ # ------------------------------------------------------------------
- name: Send Existing URL Success Notification
if: inputs.deploy_result == 'skipped' && inputs.existing_webapp_url != '' && inputs.e2e_test_result == 'success' && (inputs.TEST_SUCCESS == 'true' || inputs.TEST_SUCCESS == '')
shell: bash
@@ -261,26 +484,86 @@ jobs:
INPUT_TEST_REPORT_URL: ${{ inputs.TEST_REPORT_URL }}
ACCELERATOR_NAME: ${{ env.accelerator_name }}
LOGICAPP_URL: ${{ secrets.EMAILNOTIFICATION_LOGICAPP_URL_TA }}
- CLEANUP_STATUS: ${{ steps.cleanup.outputs.CLEANUP_STATUS }}
- RUN_E2E_TESTS: ${{ env.RUN_E2E_TESTS }}
+ CLEANUP_PILL: ${{ steps.cleanup.outputs.CLEANUP_PILL }}
+ CONFIG_LABEL: ${{ steps.config.outputs.CONFIG_LABEL }}
TEST_SUITE_NAME: ${{ steps.test_suite.outputs.TEST_SUITE_NAME }}
run: |
- RUN_URL="https://github.com/${{ env.GITHUB_REPOSITORY }}/actions/runs/${{ env.GITHUB_RUN_ID }}"
- EXISTING_URL="$INPUT_EXISTING_WEBAPP_URL"
- TEST_REPORT_URL="$INPUT_TEST_REPORT_URL"
-
- EMAIL_BODY=$(cat <Dear Team,The ${ACCELERATOR_NAME} pipeline executed against the specified Target URL and test automation has completed successfully.
Status Summary:
| Stage | Status |
|---|
| Deployment | ⏭️ SKIPPED (Tests executed on Pre-deployed RG) |
| E2E Tests | ✅ SUCCESS |
| Cleanup | ${CLEANUP_STATUS} |
Test Results:
• Test Suite: ${TEST_SUITE_NAME}
${TEST_REPORT_URL:+• Test Report: View Report}
• Target URL: ${EXISTING_URL}
Run URL: ${RUN_URL}
Best regards,
Your Automation Team
",
- "subject": "✅[CI/CD-Automation] [${ACCELERATOR_NAME}] Success"
+ # HTML-escape values that get embedded into the email template to avoid HTML/attribute injection from workflow inputs.
+ html_escape() {
+ printf '%s' "$1" | sed -e 's/&/\&/g' -e 's/\</g' -e 's/>/\>/g' -e 's/"/\"/g' -e "s/'/\'/g"
}
- EOF
+ RUN_URL="https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
+ EXISTING_URL="$(html_escape "$INPUT_EXISTING_WEBAPP_URL")"
+ TEST_REPORT_URL="$(html_escape "$INPUT_TEST_REPORT_URL")"
+ PILL_BASE="display:inline-block; min-width:70px; text-align:center; padding:4px 12px; border-radius:20px; font-size:12px; font-weight:600; line-height:1.4;"
+ DEPLOY_PILL="⏭️ SKIPPED"
+ E2E_PILL="✅ SUCCESS"
+ if [ -n "$TEST_REPORT_URL" ]; then
+ REPORT_ROW="| Test Report | 📄 View Report |
"
+ else
+ REPORT_ROW=""
+ fi
+
+ BODY_HTML=$(cat <
+
+
+
+
+ Pipeline Succeeded
+ ${ACCELERATOR_NAME} Accelerator • CI/CD Automation |
+
+ ${CONFIG_LABEL}
+ |
+
+ |
+ |
+ Dear Team, The ${ACCELERATOR_NAME} pipeline executed against the specified Target URL and test automation has completed successfully.
+
+ Status Summary
+
+ | Deployment | ${DEPLOY_PILL} |
+ | E2E Tests | ${E2E_PILL} |
+ | Cleanup | ${CLEANUP_PILL} |
+
+
+ Test Results
+
+ | Target URL |
+ ${EXISTING_URL} |
+ | Triggered By |
+ ${{ github.actor }} |
+ | Branch |
+ ${{ env.BRANCH_NAME }} |
+ | Test Suite |
+ ${TEST_SUITE_NAME} |
+ ${REPORT_ROW}
+
+
+ |
+
+
+ | CI/CD Automation Pipeline |
+ ${ACCELERATOR_NAME} Accelerator |
+
+ |
+
+ |
+
+ HTML
)
+ BODY_JSON=$(printf '%s' "$BODY_HTML" | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))')
+ PAYLOAD="{\"subject\":\"\u2705[CI/CD-Automation] [${ACCELERATOR_NAME}] Success\",\"body\":${BODY_JSON}}"
curl -X POST "${LOGICAPP_URL}" \
-H "Content-Type: application/json" \
- -d "$EMAIL_BODY" || echo "Failed to send existing URL success notification"
+ -d "$PAYLOAD" || echo "Failed to send existing URL success notification"
+ # ------------------------------------------------------------------
+ # Existing URL: test failure
+ # ------------------------------------------------------------------
- name: Send Existing URL Test Failure Notification
if: inputs.deploy_result == 'skipped' && inputs.existing_webapp_url != '' && inputs.e2e_test_result == 'failure'
shell: bash
@@ -291,22 +574,79 @@ jobs:
INPUT_TEST_REPORT_URL: ${{ inputs.TEST_REPORT_URL }}
ACCELERATOR_NAME: ${{ env.accelerator_name }}
LOGICAPP_URL: ${{ secrets.EMAILNOTIFICATION_LOGICAPP_URL_TA }}
- CLEANUP_STATUS: ${{ steps.cleanup.outputs.CLEANUP_STATUS }}
- RUN_E2E_TESTS: ${{ env.RUN_E2E_TESTS }}
+ CLEANUP_PILL: ${{ steps.cleanup.outputs.CLEANUP_PILL }}
+ CONFIG_LABEL: ${{ steps.config.outputs.CONFIG_LABEL }}
TEST_SUITE_NAME: ${{ steps.test_suite.outputs.TEST_SUITE_NAME }}
run: |
- RUN_URL="https://github.com/${{ env.GITHUB_REPOSITORY }}/actions/runs/${{ env.GITHUB_RUN_ID }}"
- EXISTING_URL="$INPUT_EXISTING_WEBAPP_URL"
- TEST_REPORT_URL="$INPUT_TEST_REPORT_URL"
-
- EMAIL_BODY=$(cat <Dear Team,The ${ACCELERATOR_NAME} pipeline executed against the specified Target URL and test automation has failed.
Status Summary:
| Stage | Status |
|---|
| Deployment | ⏭️ SKIPPED (Tests executed on Pre-deployed RG) |
| E2E Tests | ❌ FAILED |
| Cleanup | ${CLEANUP_STATUS} |
Failure Details:
• Target URL: ${EXISTING_URL}
${TEST_REPORT_URL:+• Test Report: View Report}
• Test Suite: ${TEST_SUITE_NAME}
Run URL: ${RUN_URL}
Best regards,
Your Automation Team
",
- "subject": "❌[CI/CD-Automation] [${ACCELERATOR_NAME}] E2E Test-Failed"
+ # HTML-escape values that get embedded into the email template to avoid HTML/attribute injection from workflow inputs.
+ html_escape() {
+ printf '%s' "$1" | sed -e 's/&/\&/g' -e 's/\</g' -e 's/>/\>/g' -e 's/"/\"/g' -e "s/'/\'/g"
}
- EOF
+ RUN_URL="https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
+ EXISTING_URL="$(html_escape "$INPUT_EXISTING_WEBAPP_URL")"
+ TEST_REPORT_URL="$(html_escape "$INPUT_TEST_REPORT_URL")"
+ PILL_BASE="display:inline-block; min-width:70px; text-align:center; padding:4px 12px; border-radius:20px; font-size:12px; font-weight:600; line-height:1.4;"
+ DEPLOY_PILL="⏭️ SKIPPED"
+ E2E_PILL="❌ FAILED"
+ if [ -n "$TEST_REPORT_URL" ]; then
+ REPORT_ROW="| Test Report | 📄 View Report |
"
+ else
+ REPORT_ROW=""
+ fi
+
+ BODY_HTML=$(cat <
+
+
+
+
+ E2E Tests Failed
+ ${ACCELERATOR_NAME} Accelerator • CI/CD Automation |
+
+ ${CONFIG_LABEL}
+ |
+
+ |
+ |
+ Dear Team, The ${ACCELERATOR_NAME} pipeline executed against the specified Target URL and test automation has failed.
+
+ Status Summary
+
+ | Deployment | ${DEPLOY_PILL} |
+ | E2E Tests | ${E2E_PILL} |
+ | Cleanup | ${CLEANUP_PILL} |
+
+
+ Failure Details
+
+ | Target URL |
+ ${EXISTING_URL} |
+ | Triggered By |
+ ${{ github.actor }} |
+ | Branch |
+ ${{ env.BRANCH_NAME }} |
+ | Test Suite |
+ ${TEST_SUITE_NAME} |
+ ${REPORT_ROW}
+
+
+ |
+
+
+ | CI/CD Automation Pipeline |
+ ${ACCELERATOR_NAME} Accelerator |
+
+ |
+
+ |
+
+ HTML
)
+ BODY_JSON=$(printf '%s' "$BODY_HTML" | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))')
+ PAYLOAD="{\"subject\":\"\u274C[CI/CD-Automation] [${ACCELERATOR_NAME}] E2E Test-Failed\",\"body\":${BODY_JSON}}"
curl -X POST "${LOGICAPP_URL}" \
-H "Content-Type: application/json" \
- -d "$EMAIL_BODY" || echo "Failed to send existing URL test failure notification"
+ -d "$PAYLOAD" || echo "Failed to send existing URL test failure notification"
From e5afd1676b611a37f4f01ec8706b09e0aefaa5f3 Mon Sep 17 00:00:00 2001
From: Vamshi-Microsoft
Date: Tue, 19 May 2026 12:51:51 +0530
Subject: [PATCH 2/2] refactor: reorder inputs in deploy-v2.yml for clarity
---
.github/workflows/deploy-v2.yml | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/deploy-v2.yml b/.github/workflows/deploy-v2.yml
index 2bdff5741..57253a073 100644
--- a/.github/workflows/deploy-v2.yml
+++ b/.github/workflows/deploy-v2.yml
@@ -54,13 +54,14 @@ on:
required: false
default: false
type: boolean
- enable_scalability:
- description: 'Enable Scalability (WAF only)'
+ EXP:
+ description: 'Deploy EXP'
required: false
default: false
type: boolean
- EXP:
- description: 'Deploy EXP'
+
+ enable_scalability:
+ description: 'Enable Scalability (WAF only)'
required: false
default: false
type: boolean