Skip to content

Commit 0a292fe

Browse files
CopilotJeffreyCA
andauthored
fix(azure.ai.agents): skip postdeploy hook when project has no hosted agents (#7984)
--------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: JeffreyCA <9157833+JeffreyCA@users.noreply.github.com>
1 parent 79f0500 commit 0a292fe

2 files changed

Lines changed: 39 additions & 4 deletions

File tree

cli/azd/extensions/azure.ai.agents/internal/cmd/listen.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,19 @@ func isHostedAgentService(svc *azdext.ServiceConfig, proj *azdext.ProjectConfig)
160160
}
161161

162162
func postdeployHandler(ctx context.Context, azdClient *azdext.AzdClient, args *azdext.ProjectEventArgs) error {
163+
// Skip when the project has no hosted agent services. `postdeploy` fires on every
164+
// `azd deploy`, so without this guard the AZURE_AI_PROJECT_ENDPOINT/AZURE_TENANT_ID
165+
// reads below would fail for projects that don't use this extension. See #7373.
166+
var hostedAgents []*azdext.ServiceConfig
167+
for _, svc := range args.Project.Services {
168+
if svc.Host == AiAgentHost && isHostedAgentService(svc, args.Project) {
169+
hostedAgents = append(hostedAgents, svc)
170+
}
171+
}
172+
if len(hostedAgents) == 0 {
173+
return nil
174+
}
175+
163176
// Collect agent identities from hosted agent services that were deployed.
164177
// After deploy, each hosted agent's name/version is stored as AGENT_{SERVICE_KEY}_NAME/VERSION.
165178
// We fetch the full agent version object from the API to get the instance identity principal ID,
@@ -209,10 +222,7 @@ func postdeployHandler(ctx context.Context, azdClient *azdext.AzdClient, args *a
209222

210223
// Build name→principalID map by fetching the agent version for each hosted service.
211224
agentIdentities := make(map[string]string)
212-
for _, svc := range args.Project.Services {
213-
if svc.Host != AiAgentHost || !isHostedAgentService(svc, args.Project) {
214-
continue
215-
}
225+
for _, svc := range hostedAgents {
216226
serviceKey := toServiceKey(svc.Name)
217227

218228
versionResp, err := azdClient.Environment().GetValue(ctx, &azdext.GetEnvRequest{

cli/azd/extensions/azure.ai.agents/internal/cmd/listen_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,33 @@ import (
77
"testing"
88

99
"azureaiagent/internal/project"
10+
11+
"github.com/azure/azure-dev/cli/azd/pkg/azdext"
1012
)
1113

14+
// TestPostdeployHandler_NoAgentService_NoOp verifies postdeployHandler returns nil
15+
// without any RPC calls when the project has no hosted agent services. Regression
16+
// guard for #7373.
17+
func TestPostdeployHandler_NoAgentService_NoOp(t *testing.T) {
18+
t.Parallel()
19+
20+
// Use a temp dir + explicit RelativePath so isHostedAgentService deterministically
21+
// returns false (no agent.yaml present) regardless of the test working directory.
22+
args := &azdext.ProjectEventArgs{
23+
Project: &azdext.ProjectConfig{
24+
Path: t.TempDir(),
25+
Services: map[string]*azdext.ServiceConfig{
26+
"teams-bot": {Name: "teams-bot", Host: "containerapp", RelativePath: "."},
27+
},
28+
},
29+
}
30+
31+
// nil azdClient — the early return must fire before any RPC call.
32+
if err := postdeployHandler(t.Context(), nil, args); err != nil {
33+
t.Fatalf("expected no error for project without agent services, got: %v", err)
34+
}
35+
}
36+
1237
func TestParseConnectionIDs(t *testing.T) {
1338
t.Parallel()
1439

0 commit comments

Comments
 (0)