Skip to content

Commit 96c98bc

Browse files
authored
chore(ci): scope deploy hooks to changed services (#187)
1 parent 1c285a9 commit 96c98bc

File tree

6 files changed

+127
-27
lines changed

6 files changed

+127
-27
lines changed

.github/workflows/deploy-azd.yml

Lines changed: 63 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ jobs:
5757
ui_changed: ${{ steps.detect.outputs.ui_changed }}
5858
agents_changed: ${{ steps.detect.outputs.agents_changed }}
5959
changed_agents_matrix: ${{ steps.detect.outputs.changed_agents_matrix }}
60+
changed_agent_services_csv: ${{ steps.detect.outputs.changed_agent_services_csv }}
61+
changed_aks_services_csv: ${{ steps.detect.outputs.changed_aks_services_csv }}
6062
steps:
6163
- uses: actions/checkout@v4
6264
with:
@@ -115,12 +117,13 @@ jobs:
115117
116118
AGENTS_CHANGED=false
117119
MATRIX='[]'
120+
CHANGED_AGENTS=()
118121
119122
if [ "$SHARED_CHANGED" = true ]; then
120123
AGENTS_CHANGED=true
124+
CHANGED_AGENTS=("${AGENT_SERVICES[@]}")
121125
MATRIX=$(printf '%s\n' "${AGENT_SERVICES[@]}" | jq -R . | jq -s 'map({service: .})')
122126
else
123-
CHANGED_AGENTS=()
124127
for service in "${AGENT_SERVICES[@]}"; do
125128
if echo "$CHANGED_FILES" | grep -Eq "^apps/$service/"; then
126129
CHANGED_AGENTS+=("$service")
@@ -133,10 +136,26 @@ jobs:
133136
fi
134137
fi
135138
139+
CHANGED_AGENT_SERVICES_CSV=""
140+
if [ ${#CHANGED_AGENTS[@]} -gt 0 ]; then
141+
CHANGED_AGENT_SERVICES_CSV=$(IFS=,; echo "${CHANGED_AGENTS[*]}")
142+
fi
143+
144+
CHANGED_AKS_SERVICES_CSV="$CHANGED_AGENT_SERVICES_CSV"
145+
if [ "$CRUD_CHANGED" = true ]; then
146+
if [ -n "$CHANGED_AKS_SERVICES_CSV" ]; then
147+
CHANGED_AKS_SERVICES_CSV="crud-service,$CHANGED_AKS_SERVICES_CSV"
148+
else
149+
CHANGED_AKS_SERVICES_CSV="crud-service"
150+
fi
151+
fi
152+
136153
echo "crud_changed=$CRUD_CHANGED" >> "$GITHUB_OUTPUT"
137154
echo "ui_changed=$UI_CHANGED" >> "$GITHUB_OUTPUT"
138155
echo "agents_changed=$AGENTS_CHANGED" >> "$GITHUB_OUTPUT"
139156
echo "changed_agents_matrix=$MATRIX" >> "$GITHUB_OUTPUT"
157+
echo "changed_agent_services_csv=$CHANGED_AGENT_SERVICES_CSV" >> "$GITHUB_OUTPUT"
158+
echo "changed_aks_services_csv=$CHANGED_AKS_SERVICES_CSV" >> "$GITHUB_OUTPUT"
140159
141160
provision:
142161
if: ${{ !inputs.uiOnly }}
@@ -347,7 +366,9 @@ jobs:
347366

348367
deploy-crud:
349368
runs-on: ubuntu-latest
350-
needs: provision
369+
needs:
370+
- provision
371+
- detect-changes
351372
if: ${{ !inputs.uiOnly && (!inputs.deployChangedOnly || needs.detect-changes.outputs.crud_changed == 'true') }}
352373
environment: ${{ inputs.environment }}
353374
env:
@@ -454,7 +475,9 @@ jobs:
454475
deploy-ui:
455476
runs-on: ubuntu-latest
456477
if: ${{ inputs.deployStatic && !inputs.uiOnly && (!inputs.deployChangedOnly || needs.detect-changes.outputs.ui_changed == 'true') }}
457-
needs: provision
478+
needs:
479+
- provision
480+
- detect-changes
458481
environment: ${{ inputs.environment }}
459482
env:
460483
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
@@ -574,6 +597,7 @@ jobs:
574597
runs-on: ubuntu-latest
575598
if: ${{ !inputs.uiOnly && (!inputs.deployChangedOnly || needs.detect-changes.outputs.agents_changed == 'true') }}
576599
needs:
600+
- provision
577601
- deploy-crud
578602
- deploy-foundry-models
579603
- detect-changes
@@ -645,12 +669,17 @@ jobs:
645669

646670
sync-apim:
647671
runs-on: ubuntu-latest
648-
needs: deploy-agents
672+
if: ${{ !inputs.uiOnly && (!inputs.deployChangedOnly || needs.detect-changes.outputs.agents_changed == 'true' || needs.detect-changes.outputs.crud_changed == 'true') && (needs.deploy-crud.result == 'success' || needs.deploy-crud.result == 'skipped') && (needs.deploy-agents.result == 'success' || needs.deploy-agents.result == 'skipped') }}
673+
needs:
674+
- deploy-crud
675+
- deploy-agents
676+
- detect-changes
649677
environment: ${{ inputs.environment }}
650678
env:
651679
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
652680
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
653681
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
682+
CHANGED_SERVICES: ${{ inputs.deployChangedOnly && needs.detect-changes.outputs.changed_aks_services_csv || '' }}
654683
steps:
655684
- uses: actions/checkout@v4
656685

@@ -677,12 +706,16 @@ jobs:
677706

678707
ensure-foundry-agents:
679708
runs-on: ubuntu-latest
680-
needs: deploy-agents
709+
if: ${{ !inputs.uiOnly && (!inputs.deployChangedOnly || needs.detect-changes.outputs.agents_changed == 'true') && (needs.deploy-agents.result == 'success' || needs.deploy-agents.result == 'skipped') }}
710+
needs:
711+
- deploy-agents
712+
- detect-changes
681713
environment: ${{ inputs.environment }}
682714
env:
683715
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
684716
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
685717
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
718+
CHANGED_SERVICES: ${{ inputs.deployChangedOnly && needs.detect-changes.outputs.changed_agent_services_csv || '' }}
686719
steps:
687720
- uses: actions/checkout@v4
688721

@@ -713,27 +746,31 @@ jobs:
713746

714747
- name: Verify Foundry readiness across services
715748
run: |
716-
SERVICES=$(python3 -c "
717-
import re
718-
with open('azure.yaml') as f: lines = f.readlines()
719-
s, cs, ch = False, None, None
720-
svcs = []
721-
for l in lines:
722-
l = l.rstrip()
723-
if not s:
724-
if re.match(r'^services:\s*$', l): s = True
725-
continue
726-
if re.match(r'^[^\s]', l): break
727-
m = re.match(r'^ ([a-z0-9\-]+):\s*$', l)
728-
if m:
729-
if cs and ch == 'aks' and cs != 'crud-service': svcs.append(cs)
730-
cs, ch = m.group(1), None
731-
continue
732-
h = re.match(r'^ host:\s*(\S+)', l)
733-
if h: ch = h.group(1)
734-
if cs and ch == 'aks' and cs != 'crud-service': svcs.append(cs)
735-
print('\n'.join(svcs))
736-
")
749+
if [ -n "${CHANGED_SERVICES}" ]; then
750+
SERVICES=$(printf '%s' "${CHANGED_SERVICES}" | tr ',' '\n' | sed '/^crud-service$/d' | sed '/^$/d')
751+
else
752+
SERVICES=$(python3 -c "
753+
import re
754+
with open('azure.yaml') as f: lines = f.readlines()
755+
s, cs, ch = False, None, None
756+
svcs = []
757+
for l in lines:
758+
l = l.rstrip()
759+
if not s:
760+
if re.match(r'^services:\s*$', l): s = True
761+
continue
762+
if re.match(r'^[^\s]', l): break
763+
m = re.match(r'^ ([a-z0-9\-]+):\s*$', l)
764+
if m:
765+
if cs and ch == 'aks' and cs != 'crud-service': svcs.append(cs)
766+
cs, ch = m.group(1), None
767+
continue
768+
h = re.match(r'^ host:\s*(\S+)', l)
769+
if h: ch = h.group(1)
770+
if cs and ch == 'aks' and cs != 'crud-service': svcs.append(cs)
771+
print('\\n'.join(svcs))
772+
")
773+
fi
737774
738775
FAILED=0
739776
echo "$SERVICES" | while IFS= read -r SVC; do

.infra/azd/hooks/ensure-foundry-agents.ps1

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ param(
3333
[switch]$UsePortForward,
3434
[string]$BaseUrl,
3535
[string]$AzureYamlPath,
36+
[string]$ChangedServices = $env:CHANGED_SERVICES,
3637
[int]$MaxRetries = 3,
3738
[bool]$FailOnError = $false
3839
)
@@ -140,6 +141,17 @@ function Resolve-K8sServiceEndpoint {
140141

141142
# ---- Main ----
142143
$services = Get-AgentServices -Path $AzureYamlPath
144+
145+
if ($ChangedServices) {
146+
$changedServiceSet = $ChangedServices.Split(',') | ForEach-Object { $_.Trim() } | Where-Object { $_ }
147+
$services = @($services | Where-Object { $changedServiceSet -contains $_ })
148+
}
149+
150+
if (-not $services -or $services.Count -eq 0) {
151+
Write-Host 'No matching changed agent services to ensure.'
152+
exit 0
153+
}
154+
143155
Write-Host "Found $($services.Count) agent services to ensure."
144156

145157
$failed = @()

.infra/azd/hooks/ensure-foundry-agents.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ MAX_RETRIES="${MAX_RETRIES:-3}"
1515
USE_PORT_FORWARD=false
1616
BASE_URL=""
1717
FAIL_ON_ERROR="${FAIL_ON_ERROR:-false}"
18+
CHANGED_SERVICES="${CHANGED_SERVICES:-}"
1819

1920
# ---- Parse arguments ----
2021
while [ $# -gt 0 ]; do
@@ -68,6 +69,23 @@ if [ -z "$SERVICES" ]; then
6869
exit 0
6970
fi
7071

72+
if [ -n "$CHANGED_SERVICES" ]; then
73+
FILTER_FILE="$(mktemp)"
74+
printf '%s' "$CHANGED_SERVICES" | tr ',' '\n' | sed '/^[[:space:]]*$/d' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' > "$FILTER_FILE"
75+
SERVICES="$(printf '%s\n' "$SERVICES" | while IFS= read -r SVC; do
76+
[ -z "$SVC" ] && continue
77+
if grep -Fxq "$SVC" "$FILTER_FILE"; then
78+
printf '%s\n' "$SVC"
79+
fi
80+
done)"
81+
rm -f "$FILTER_FILE"
82+
fi
83+
84+
if [ -z "$SERVICES" ]; then
85+
echo "No matching changed agent services to ensure."
86+
exit 0
87+
fi
88+
7189
SERVICE_COUNT="$(echo "$SERVICES" | wc -l | tr -d ' ')"
7290
echo "Found $SERVICE_COUNT agent services to ensure."
7391

.infra/azd/hooks/sync-apim-agents.ps1

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ param(
33
[string]$ApimName = $env:APIM_NAME,
44
[string]$Namespace = $(if ($env:K8S_NAMESPACE) { $env:K8S_NAMESPACE } else { 'holiday-peak' }),
55
[string]$AzureYamlPath,
6+
[string]$ChangedServices = $env:CHANGED_SERVICES,
67
[string]$ApiPathPrefix = 'agents',
78
[bool]$IncludeCrudService = $true,
89
[bool]$RequireLoadBalancer = $true,
@@ -522,8 +523,14 @@ $script:resolvedAksClusterName = Get-AksClusterName -Rg $resolvedResourceGroup -
522523
Ensure-AksCredentials -Rg $resolvedResourceGroup -RepoRoot $repoRoot -SkipForPreview:$Preview
523524

524525
$agentServices = Get-AksServicesFromAzureYaml -Path $AzureYamlPath -IncludeCrud:$IncludeCrudService
526+
527+
if ($ChangedServices) {
528+
$changedServiceSet = $ChangedServices.Split(',') | ForEach-Object { $_.Trim() } | Where-Object { $_ }
529+
$agentServices = @($agentServices | Where-Object { $changedServiceSet -contains $_ })
530+
}
531+
525532
if (-not $agentServices -or $agentServices.Count -eq 0) {
526-
Write-Host 'No AKS agent services were found in azure.yaml. Nothing to sync.'
533+
Write-Host 'No matching changed AKS services to sync.'
527534
exit 0
528535
}
529536

.infra/azd/hooks/sync-apim-agents.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ REPO_ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
66
AZURE_YAML_PATH="${AZURE_YAML_PATH:-$REPO_ROOT/azure.yaml}"
77
NAMESPACE="${K8S_NAMESPACE:-holiday-peak}"
88
API_PATH_PREFIX="${API_PATH_PREFIX:-agents}"
9+
CHANGED_SERVICES="${CHANGED_SERVICES:-}"
910
RESOURCE_GROUP="${AZURE_RESOURCE_GROUP:-${RESOURCE_GROUP:-}}"
1011
APIM_NAME="${APIM_NAME:-}"
1112
AKS_CLUSTER_NAME="${AKS_CLUSTER_NAME:-}"
@@ -169,6 +170,23 @@ if [ -z "$SERVICES" ]; then
169170
exit 0
170171
fi
171172

173+
if [ -n "$CHANGED_SERVICES" ]; then
174+
FILTER_FILE="$(mktemp)"
175+
printf '%s' "$CHANGED_SERVICES" | tr ',' '\n' | sed '/^[[:space:]]*$/d' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' > "$FILTER_FILE"
176+
SERVICES="$(printf '%s\n' "$SERVICES" | while IFS= read -r SERVICE; do
177+
[ -z "$SERVICE" ] && continue
178+
if grep -Fxq "$SERVICE" "$FILTER_FILE"; then
179+
printf '%s\n' "$SERVICE"
180+
fi
181+
done)"
182+
rm -f "$FILTER_FILE"
183+
fi
184+
185+
if [ -z "$SERVICES" ]; then
186+
echo "No matching changed AKS services to sync."
187+
exit 0
188+
fi
189+
172190
echo "Syncing APIM APIs for AKS agent services into $APIM_NAME (RG: $RESOURCE_GROUP)..."
173191
174192
resolve_backend_url() {

docs/implementation/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,14 @@ Target: **100%**
149149

150150
---
151151

152+
## Deployment Optimization
153+
154+
- `deploy-azd` changed-service detection now publishes changed agent and AKS service lists.
155+
- Post-deploy hooks (`sync-apim-agents` and `ensure-foundry-agents`) consume these lists through `CHANGED_SERVICES` and run only for changed services when `deployChangedOnly=true`.
156+
- Foundry readiness verification in deployment workflow is scoped to changed agent services under changed-only mode.
157+
158+
---
159+
152160
## Related Documentation
153161

154162
- [Architecture Overview](../architecture/architecture.md)

0 commit comments

Comments
 (0)