Skip to content

Commit 16ebca1

Browse files
Merge branch 'main' into dev
2 parents 2952b2a + 7001d1d commit 16ebca1

36 files changed

+3586
-2725
lines changed

.devcontainer/setupEnv.sh

100644100755
File mode changed.

.github/dependabot.yml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
version: 2
55
updates:
6-
# GitHub Actions dependencies
6+
# GitHub Actions dependencies (grouped)
77
- package-ecosystem: "github-actions"
88
directory: "/"
99
schedule:
@@ -12,7 +12,12 @@ updates:
1212
prefix: "build"
1313
target-branch: "dependabotchanges"
1414
open-pull-requests-limit: 10
15+
groups:
16+
all-actions:
17+
patterns:
18+
- "*"
1519

20+
# Python pip dependencies (grouped)
1621
- package-ecosystem: "pip"
1722
directory: "/src/backend"
1823
schedule:
@@ -21,6 +26,10 @@ updates:
2126
prefix: "build"
2227
target-branch: "dependabotchanges"
2328
open-pull-requests-limit: 10
29+
groups:
30+
python-deps:
31+
patterns:
32+
- "*"
2433

2534
- package-ecosystem: "pip"
2635
directory: "/src/frontend"
@@ -29,4 +38,8 @@ updates:
2938
commit-message:
3039
prefix: "build"
3140
target-branch: "dependabotchanges"
32-
open-pull-requests-limit: 10
41+
open-pull-requests-limit: 10
42+
groups:
43+
python-deps:
44+
patterns:
45+
- "*"

.github/workflows/deploy.yml

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ jobs:
100100
set -e
101101
az deployment group create \
102102
--resource-group ${{ env.RESOURCE_GROUP_NAME }} \
103-
--template-file infra/macae.bicep \
104-
--parameters azureOpenAILocation=${{env.AZURE_LOCATION }} cosmosLocation=${{env.AZURE_LOCATION }}
103+
--template-file infra/main.bicep \
104+
--parameters azureOpenAILocation=${{ env.AZURE_LOCATION }}
105105
106106
107107
- name: Send Notification on Failure
@@ -123,7 +123,7 @@ jobs:
123123
-d "$EMAIL_BODY" || echo "Failed to send notification"
124124

125125

126-
- name: Get OpenAI, App Service and Container Registry Resource from Resource Group
126+
- name: Get OpenAI Resource from Resource Group
127127
id: get_openai_resource
128128
run: |
129129
@@ -142,35 +142,11 @@ jobs:
142142
echo "OpenAI resource name: ${openai_resource_name}"
143143
fi
144144
145-
echo "Fetching Azure App Service resource from resource group ${{ env.RESOURCE_GROUP_NAME }}..."
146145
147-
# Run the az resource list command to get the App Service resource name
148-
app_service_name=$(az resource list --resource-group ${{ env.RESOURCE_GROUP_NAME }} --resource-type "Microsoft.Web/sites" --query "[0].name" -o tsv)
149-
150-
if [ -z "$app_service_name" ]; then
151-
echo "No Azure App Service resource found in resource group ${{ env.RESOURCE_GROUP_NAME }}."
152-
exit 1
153-
else
154-
echo "APP_SERVICE_NAME=${app_service_name}" >> $GITHUB_ENV
155-
echo "Azure App Service resource name: ${app_service_name}"
156-
fi
157-
158-
echo "Fetching container registry resource from resource group ${{ env.RESOURCE_GROUP_NAME }}..."
159-
160-
# Fetch Azure Container Registry name
161-
acr_name=$(az acr list --resource-group ${{ env.RESOURCE_GROUP_NAME }} --query "[0].name" -o tsv)
162-
163-
if [ -z "$acr_name" ]; then
164-
echo "No Azure Container Registry found in resource group ${{ env.RESOURCE_GROUP_NAME }}."
165-
exit 1
166-
else
167-
echo "ACR_NAME=${acr_name}" >> $GITHUB_ENV
168-
echo "Azure Container Registry name: ${acr_name}"
169-
fi
170146
171147
172148
- name: Delete Bicep Deployment
173-
if: success()
149+
if: always()
174150
run: |
175151
set -e
176152
echo "Checking if resource group exists..."
@@ -240,7 +216,7 @@ jobs:
240216
241217
242218
- name: Purging the Resources
243-
if: success()
219+
if: always()
244220
run: |
245221
246222
set -e

.github/workflows/docker-build-and-push.yml

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,18 @@ jobs:
3535
if: ${{ github.ref_name == 'main' || github.ref_name == 'dev' || github.ref_name == 'demo' || github.ref_name == 'hotfix' }}
3636
uses: azure/docker-login@v2
3737
with:
38-
login-server: ${{ secrets.ACR_LOGIN_SERVER }}
38+
login-server: ${{ secrets.ACR_LOGIN_SERVER || 'acrlogin.azurecr.io' }}
3939
username: ${{ secrets.ACR_USERNAME }}
4040
password: ${{ secrets.ACR_PASSWORD }}
4141

4242
- name: Get current date
4343
id: date
4444
run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
45+
46+
- name: Get registry
47+
id: registry
48+
run: |
49+
echo "ext_registry=${{ secrets.ACR_LOGIN_SERVER || 'acrlogin.azurecr.io'}}" >> $GITHUB_OUTPUT
4550
4651
- name: Determine Tag Name Based on Branch
4752
id: determine_tag
@@ -72,8 +77,8 @@ jobs:
7277
file: ./src/backend/Dockerfile
7378
push: ${{ env.TAG != 'pullrequest-ignore' }}
7479
tags: |
75-
${{ secrets.ACR_LOGIN_SERVER }}/macaebackend:${{ env.TAG }}
76-
${{ secrets.ACR_LOGIN_SERVER }}/macaebackend:${{ env.HISTORICAL_TAG }}
80+
${{ steps.registry.outputs.ext_registry }}/macaebackend:${{ env.TAG }}
81+
${{ steps.registry.outputs.ext_registry }}/macaebackend:${{ env.HISTORICAL_TAG }}
7782
7883
- name: Build and optionally push Frontend Docker image
7984
uses: docker/build-push-action@v6
@@ -82,5 +87,5 @@ jobs:
8287
file: ./src/frontend/Dockerfile
8388
push: ${{ env.TAG != 'pullrequest-ignore' }}
8489
tags: |
85-
${{ secrets.ACR_LOGIN_SERVER }}/macaefrontend:${{ env.TAG }}
86-
${{ secrets.ACR_LOGIN_SERVER }}/macaefrontend:${{ env.HISTORICAL_TAG }}
90+
${{ steps.registry.outputs.ext_registry }}/macaefrontend:${{ env.TAG }}
91+
${{ steps.registry.outputs.ext_registry }}/macaefrontend:${{ env.HISTORICAL_TAG }}
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# ------------------------------------------------------------------------------
2+
# Scheduled Dependabot PRs Auto-Merge Workflow
3+
#
4+
# Purpose:
5+
# - Automatically detect, rebase (if needed), and merge Dependabot PRs targeting
6+
# the `dependabotchanges` branch, supporting different merge strategies.
7+
#
8+
# Features:
9+
# ✅ Filters PRs authored by Dependabot and targets the specific base branch
10+
# ✅ Rebases PRs with conflicts and auto-resolves using "prefer-theirs" strategy
11+
# ✅ Attempts all three merge strategies: merge, squash, rebase (first success wins)
12+
# ✅ Handles errors gracefully, logs clearly
13+
#
14+
# Triggers:
15+
# - Scheduled daily run (midnight UTC)
16+
# - Manual trigger (via GitHub UI)
17+
#
18+
# Required Permissions:
19+
# - contents: write
20+
# - pull-requests: write
21+
# ------------------------------------------------------------------------------
22+
23+
name: Scheduled Dependabot PRs Auto-Merge
24+
25+
on:
26+
schedule:
27+
- cron: '0 0 * * *' # Runs once a day at midnight UTC
28+
workflow_dispatch:
29+
30+
permissions:
31+
contents: write
32+
pull-requests: write
33+
34+
jobs:
35+
merge-dependabot:
36+
runs-on: ubuntu-latest
37+
steps:
38+
- name: Checkout repository
39+
uses: actions/checkout@v4
40+
41+
- name: Install GitHub CLI
42+
run: |
43+
sudo apt update
44+
sudo apt install -y gh
45+
- name: Fetch & Filter Dependabot PRs
46+
env:
47+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
48+
run: |
49+
echo "🔍 Fetching all Dependabot PRs targeting 'dependabotchanges'..."
50+
> matched_prs.txt
51+
pr_batch=$(gh pr list --state open --json number,title,author,baseRefName,url \
52+
--jq '.[] | "\(.number)|\(.title)|\(.author.login)|\(.baseRefName)|\(.url)"')
53+
while IFS='|' read -r number title author base url; do
54+
author=$(echo "$author" | xargs)
55+
base=$(echo "$base" | xargs)
56+
if [[ "$author" == "app/dependabot" && "$base" == "dependabotchanges" ]]; then
57+
echo "$url" >> matched_prs.txt
58+
echo "✅ Matched PR #$number - $title"
59+
else
60+
echo "❌ Skipped PR #$number - $title (Author: $author, Base: $base)"
61+
fi
62+
done <<< "$pr_batch"
63+
echo "👉 Matched PRs:"
64+
cat matched_prs.txt || echo "None"
65+
- name: Rebase PR if Conflicts Exist
66+
if: success()
67+
env:
68+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
69+
run: |
70+
if [[ ! -s matched_prs.txt ]]; then
71+
echo "⚠️ No matching PRs to process."
72+
exit 0
73+
fi
74+
while IFS= read -r pr_url; do
75+
pr_number=$(basename "$pr_url")
76+
echo "🔁 Checking PR #$pr_number for conflicts..."
77+
mergeable=$(gh pr view "$pr_number" --json mergeable --jq '.mergeable')
78+
if [[ "$mergeable" == "CONFLICTING" ]]; then
79+
echo "⚠️ Merge conflicts detected. Performing manual rebase for PR #$pr_number..."
80+
head_branch=$(gh pr view "$pr_number" --json headRefName --jq '.headRefName')
81+
base_branch=$(gh pr view "$pr_number" --json baseRefName --jq '.baseRefName')
82+
git fetch origin "$base_branch":"$base_branch"
83+
git fetch origin "$head_branch":"$head_branch"
84+
git checkout "$head_branch"
85+
git config user.name "github-actions"
86+
git config user.email "[email protected]"
87+
# Attempt rebase with 'theirs' strategy
88+
if git rebase --strategy=recursive -X theirs "$base_branch"; then
89+
echo "✅ Rebase successful. Pushing..."
90+
git push origin "$head_branch" --force
91+
else
92+
echo "❌ Rebase failed. Aborting..."
93+
git rebase --abort || true
94+
fi
95+
else
96+
echo "✅ PR #$pr_number is mergeable. Skipping rebase."
97+
fi
98+
done < matched_prs.txt
99+
100+
- name: Auto-Merge PRs using available strategy
101+
if: success()
102+
env:
103+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
104+
run: |
105+
if [[ ! -s matched_prs.txt ]]; then
106+
echo "⚠️ No matching PRs to process."
107+
exit 0
108+
fi
109+
while IFS= read -r pr_url; do
110+
pr_number=$(basename "$pr_url")
111+
echo "🔍 Checking mergeability for PR #$pr_number"
112+
attempt=0
113+
max_attempts=8
114+
mergeable=""
115+
sleep 5 # Let GitHub calculate mergeable status
116+
while [[ $attempt -lt $max_attempts ]]; do
117+
mergeable=$(gh pr view "$pr_number" --json mergeable --jq '.mergeable' 2>/dev/null || echo "UNKNOWN")
118+
echo "🔁 Attempt $((attempt+1))/$max_attempts: mergeable=$mergeable"
119+
if [[ "$mergeable" == "MERGEABLE" ]]; then
120+
success=0
121+
for strategy in rebase squash merge; do
122+
echo "🚀 Trying to auto-merge PR #$pr_number using '$strategy' strategy..."
123+
set -x
124+
merge_output=$(gh pr merge --auto --"$strategy" "$pr_url" 2>&1)
125+
merge_status=$?
126+
set +x
127+
echo "$merge_output"
128+
if [[ $merge_status -eq 0 ]]; then
129+
echo "✅ Auto-merge succeeded using '$strategy'."
130+
success=1
131+
break
132+
else
133+
echo "❌ Auto-merge failed using '$strategy'. Trying next strategy..."
134+
fi
135+
done
136+
if [[ $success -eq 0 ]]; then
137+
echo "❌ All merge strategies failed for PR #$pr_number"
138+
fi
139+
break
140+
elif [[ "$mergeable" == "CONFLICTING" ]]; then
141+
echo "❌ Cannot merge due to conflicts. Skipping PR #$pr_number"
142+
break
143+
else
144+
echo "🕒 Waiting for GitHub to determine mergeable status..."
145+
sleep 15
146+
fi
147+
((attempt++))
148+
done
149+
if [[ "$mergeable" != "MERGEABLE" && "$mergeable" != "CONFLICTING" ]]; then
150+
echo "❌ Mergeability undetermined after $max_attempts attempts. Skipping PR #$pr_number"
151+
fi
152+
done < matched_prs.txt || echo "⚠️ Completed loop with some errors, but continuing gracefully."

README.md

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@ The solution leverages Azure OpenAI Service, Azure Container Apps, Azure Cosmos
2525
|![image](./documentation/images/readme/macae-architecture.png)|
2626
|---|
2727

28-
### Application interface
29-
|![image](./documentation/images/readme/macae-application.png)|
30-
|---|
28+
3129

3230
### How to customize
3331
If you'd like to customize the solution accelerator, here are some common areas to start:
@@ -51,7 +49,7 @@ If you'd like to customize the solution accelerator, here are some common areas
5149
<summary>Click to learn more about the key features this solution enables</summary>
5250

5351
- **Allows people to focus on what matters** <br/>
54-
By doing the heavy lifting involved with coordinating activities across an organization, peoples' time is freed up to focus on their specializations.
52+
By doing the heavy lifting involved with coordinating activities across an organization, people's time is freed up to focus on their specializations.
5553

5654
- **Enabling GenAI to scale** <br/>
5755
By not needing to build one application after another, organizations are able to reduce the friction of adopting GenAI across their entire organization. One capability can unlock almost unlimited use cases.
@@ -95,7 +93,7 @@ Here are some example regions where the services are available: East US, East US
9593

9694
Pricing varies per region and usage, so it isn't possible to predict exact costs for your usage. The majority of the Azure resources used in this infrastructure are on usage-based pricing tiers. However, Azure Container Registry has a fixed cost per registry per day.
9795

98-
Use the [Azure pricing calculator](https://azure.microsoft.com/en-us/pricing/calculator) to calculate the cost of this solution in your subscription. [Review a sample pricing sheet for the achitecture](https://azure.com/e/86d0eefbe4dd4a23981c1d3d4f6fe7ed).
96+
Use the [Azure pricing calculator](https://azure.microsoft.com/en-us/pricing/calculator) to calculate the cost of this solution in your subscription. [Review a sample pricing sheet for the architecture](https://azure.com/e/86d0eefbe4dd4a23981c1d3d4f6fe7ed).
9997
| Product | Description | Cost |
10098
|---|---|---|
10199
| [Azure OpenAI Service](https://learn.microsoft.com/azure/ai-services/openai/) | Powers the AI agents for task automation | [Pricing](https://azure.microsoft.com/pricing/details/cognitive-services/openai-service/) |
@@ -199,6 +197,6 @@ You must also comply with all domestic and international export laws and regulat
199197

200198
You acknowledge that the Software and Microsoft Products and Services (1) are not designed, intended or made available as a medical device(s), and (2) are not designed or intended to be a substitute for professional medical advice, diagnosis, treatment, or judgment and should not be used to replace or as a substitute for professional medical advice, diagnosis, treatment, or judgment. Customer is solely responsible for displaying and/or obtaining appropriate consents, warnings, disclaimers, and acknowledgements to end users of Customer's implementation of the Online Services.
201199

202-
You acknowledge the Software is not subject to SOC 1 and SOC 2 compliance audits. No Microsoft technology, nor any of its component technologies, including the Software, is intended or made available as a substitute for the professional advice, opinion, or judgement of a certified financial services professional. Do not use the Software to replace, substitute, or provide professional financial advice or judgment.
200+
You acknowledge the Software is not subject to SOC 1 and SOC 2 compliance audits. No Microsoft technology, nor any of its component technologies, including the Software, is intended or made available as a substitute for the professional advice, opinion, or judgment of a certified financial services professional. Do not use the Software to replace, substitute, or provide professional financial advice or judgment.
203201

204-
BY ACCESSING OR USING THE SOFTWARE, YOU ACKNOWLEDGE THAT THE SOFTWARE IS NOT DESIGNED OR INTENDED TO SUPPORT ANY USE IN WHICH A SERVICE INTERRUPTION, DEFECT, ERROR, OR OTHER FAILURE OF THE SOFTWARE COULD RESULT IN THE DEATH OR SERIOUS BODILY INJURY OF ANY PERSON OR IN PHYSICAL OR ENVIRONMENTAL DAMAGE (COLLECTIVELY, "HIGH-RISK USE"), AND THAT YOU WILL ENSURE THAT, IN THE EVENT OF ANY INTERRUPTION, DEFECT, ERROR, OR OTHER FAILURE OF THE SOFTWARE, THE SAFETY OF PEOPLE, PROPERTY, AND THE ENVIRONMENT ARE NOT REDUCED BELOW A LEVEL THAT IS REASONABLY, APPROPRIATE, AND LEGAL, WHETHER IN GENERAL OR IN A SPECIFIC INDUSTRY. BY ACCESSING THE SOFTWARE, YOU FURTHER ACKNOWLEDGE THAT YOUR HIGH-RISK USE OF THE SOFTWARE IS AT YOUR OWN RISK.
202+
BY ACCESSING OR USING THE SOFTWARE, YOU ACKNOWLEDGE THAT THE SOFTWARE IS NOT DESIGNED OR INTENDED TO SUPPORT ANY USE IN WHICH A SERVICE INTERRUPTION, DEFECT, ERROR, OR OTHER FAILURE OF THE SOFTWARE COULD RESULT IN THE DEATH OR SERIOUS BODILY INJURY OF ANY PERSON OR IN PHYSICAL OR ENVIRONMENTAL DAMAGE (COLLECTIVELY, "HIGH-RISK USE"), AND THAT YOU WILL ENSURE THAT, IN THE EVENT OF ANY INTERRUPTION, DEFECT, ERROR, OR OTHER FAILURE OF THE SOFTWARE, THE SAFETY OF PEOPLE, PROPERTY, AND THE ENVIRONMENT ARE NOT REDUCED BELOW A LEVEL THAT IS REASONABLY, APPROPRIATE, AND LEGAL, WHETHER IN GENERAL OR IN A SPECIFIC INDUSTRY. BY ACCESSING THE SOFTWARE, YOU FURTHER ACKNOWLEDGE THAT YOUR HIGH-RISK USE OF THE SOFTWARE IS AT YOUR OWN RISK.

docs/azure_app_service_auth_setup.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
![Web](./images/azure-app-service-auth-setup/Web.png)
5454

5555
8. Enter the `web app URL` (Provide the app service name in place of XXXX) and Save. Then go back to [Step 1](#step-1-add-authentication-in-azure-app-service-configuration) and follow from _Point 4_ choose `Pick an existing app registration in this directory` from the Add an Identity Provider page and provide the newly registered App Name.
56-
E.g. https://appservicename.azurewebsites.net/.auth/login/aad/callback
56+
E.g. <<https://<< appservicename >>.azurewebsites.net/.auth/login/aad/callback>>
5757

5858
![Add Details](./images/azure-app-service-auth-setup/WebAppURL.png)

0 commit comments

Comments
 (0)