Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
89b8eed
Merge pull request #752 from microsoft/dev-v4
Prajwal-Microsoft Jan 5, 2026
db3d217
fix: Map inputs to environment variables and Add input validation for…
Vamshi-Microsoft Jan 6, 2026
53a3696
Minor fixes
Vamshi-Microsoft Jan 6, 2026
fc28b6d
Update variable case
Vamshi-Microsoft Jan 6, 2026
dec500a
fix: Reorder EXP validation step
Vamshi-Microsoft Jan 6, 2026
e4a0369
Merge branch 'psl-30705' of https://github.com/microsoft/Multi-Agent-…
Vamshi-Microsoft Jan 6, 2026
73c9016
remove unused variable
Vamshi-Microsoft Jan 6, 2026
621ea95
fix: Update AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID validation regex for…
Vamshi-Microsoft Jan 6, 2026
9a46db0
Merge pull request #757 from microsoft/psl-30705
Prajwal-Microsoft Jan 6, 2026
25d6537
fixed vulnerabilities
Vamshi-Microsoft Jan 8, 2026
9ea6472
fix: update job name
Vamshi-Microsoft Jan 8, 2026
82fcd1e
fix: fallback to default ACR login server if not set in secrets to re…
Vamshi-Microsoft Jan 8, 2026
d406f5c
Merge pull request #761 from microsoft/psl-fix-vulnerabilities
Prajwal-Microsoft Jan 8, 2026
c606823
fix: remove Curl for azure cli setup
Vamshi-Microsoft Jan 8, 2026
ad52331
Merge pull request #763 from microsoft/psl-fix-curl
Prajwal-Microsoft Jan 12, 2026
585b393
chore: dev-v4 to main
Avijit-Microsoft Jan 12, 2026
4a8e8ba
fixed Pipeline failures
Vamshi-Microsoft Jan 13, 2026
8702239
Enhance EXP configuration handling in deployment workflow
Vamshi-Microsoft Jan 13, 2026
7f2f6a6
fix: update IMAGE_TAG format for dev-v4 branch
Vamshi-Microsoft Jan 16, 2026
327dcef
Merge pull request #768 from microsoft/psl-fix-pipeline-failures
Prajwal-Microsoft Jan 16, 2026
9f8c37d
Merge pull request #773 from microsoft/dev-v4
Roopan-Microsoft Jan 19, 2026
cb56a0b
chore: remove AZURE_DEV_COLLECT_TELEMETRY environment variable
Abdul-Microsoft Jan 20, 2026
e908959
removed telemetry flag from output
Abdul-Microsoft Jan 20, 2026
997c7f0
Merge pull request #774 from microsoft/psl-removetelemetryflag
Roopan-Microsoft Jan 20, 2026
30997db
fix the issue with devconatiner
Prekshith-Microsoft Jan 28, 2026
092af3a
Merge pull request #784 from microsoft/psl-devconissue
Prajwal-Microsoft Jan 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FROM mcr.microsoft.com/devcontainers/python:3.11-bullseye

# Remove Yarn repository to avoid GPG key expiration issue
RUN rm -f /etc/apt/sources.list.d/yarn.list
4 changes: 3 additions & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{
"name": "Multi Agent Custom Automation Engine Solution Accelerator",
"image": "mcr.microsoft.com/devcontainers/python:3.11-bullseye",
"build": {
"dockerfile": "Dockerfile"
},
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {"version": "latest"},
"ghcr.io/azure/azure-dev/azd:latest": {},
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/azure-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
uses: actions/checkout@v4
# Step 2: Validate the Azure template using microsoft/template-validation-action
- name: Validate Azure Template
uses: microsoft/template-validation-action@Latest
uses: microsoft/template-validation-action@bae4895d0a8abd4f0d5aad68ae8647b3027f4c91
with:
validateAzd: true
useDevContainer: false
Expand Down
192 changes: 182 additions & 10 deletions .github/workflows/deploy-linux.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
name: Deploy-Test-Cleanup (v2) Linux

permissions:
contents: read
actions: read
on:
workflow_run:
workflows: ["Build Docker and Optional Push v4"]
Expand Down Expand Up @@ -82,19 +86,187 @@ on:
- 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: ${{ github.event.inputs.azure_location || 'australiaeast' }}
resource_group_name: ${{ github.event.inputs.resource_group_name || '' }}
waf_enabled: ${{ github.event.inputs.waf_enabled == 'true' }}
EXP: ${{ github.event.inputs.EXP == 'true' }}
build_docker_image: ${{ github.event.inputs.build_docker_image == 'true' }}
cleanup_resources: ${{ github.event.inputs.cleanup_resources == 'true' }}
run_e2e_tests: ${{ github.event.inputs.run_e2e_tests || 'GoldenPath-Testing' }}
AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID: ${{ github.event.inputs.AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID || '' }}
AZURE_EXISTING_AI_PROJECT_RESOURCE_ID: ${{ github.event.inputs.AZURE_EXISTING_AI_PROJECT_RESOURCE_ID || '' }}
existing_webapp_url: ${{ github.event.inputs.existing_webapp_url || '' }}
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
6 changes: 5 additions & 1 deletion .github/workflows/deploy-orchestrator.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
name: Deployment orchestrator

permissions:
contents: read
actions: read

on:
workflow_call:
inputs:
Expand Down Expand Up @@ -74,7 +78,7 @@ jobs:
secrets: inherit

deploy:
if: "!cancelled() && (inputs.trigger_type != 'workflow_dispatch' || inputs.existing_webapp_url == '' || inputs.existing_webapp_url == null)"
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)"
needs: docker-build
uses: ./.github/workflows/job-deploy.yml
with:
Expand Down
26 changes: 12 additions & 14 deletions .github/workflows/deploy-waf.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
name: Validate WAF Deployment v4

permissions:
contents: read
actions: read
on:
push:
branches:
Expand All @@ -20,16 +23,16 @@ jobs:

- name: Run Quota Check
id: quota-check
env:
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
GPT_MIN_CAPACITY: ${{ env.GPT_MIN_CAPACITY }}
O4_MINI_MIN_CAPACITY: ${{ env.O4_MINI_MIN_CAPACITY }}
GPT41_MINI_MIN_CAPACITY: ${{ env.GPT41_MINI_MIN_CAPACITY }}
AZURE_REGIONS: ${{ vars.AZURE_REGIONS }}
run: |
export AZURE_CLIENT_ID=${{ secrets.AZURE_CLIENT_ID }}
export AZURE_TENANT_ID=${{ secrets.AZURE_TENANT_ID }}
export AZURE_CLIENT_SECRET=${{ secrets.AZURE_CLIENT_SECRET }}
export AZURE_SUBSCRIPTION_ID="${{ secrets.AZURE_SUBSCRIPTION_ID }}"
export GPT_MIN_CAPACITY="1"
export O4_MINI_MIN_CAPACITY="1"
export GPT41_MINI_MIN_CAPACITY="1"
export AZURE_REGIONS="${{ vars.AZURE_REGIONS }}"

chmod +x infra/scripts/checkquota.sh
if ! infra/scripts/checkquota.sh; then
# If quota check fails due to insufficient quota, set the flag
Expand Down Expand Up @@ -63,11 +66,6 @@ jobs:
echo "Selected Region: $VALID_REGION"
echo "AZURE_LOCATION=$VALID_REGION" >> $GITHUB_ENV

- name: Setup Azure CLI
run: |
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
az --version # Verify installation

- name: Login to Azure
run: |
az login --service-principal -u ${{ secrets.AZURE_CLIENT_ID }} -p ${{ secrets.AZURE_CLIENT_SECRET }} --tenant ${{ secrets.AZURE_TENANT_ID }}
Expand Down
Loading
Loading