fix(agents): resolve project root for infra eject#9291
Conversation
📋 Prioritization NoteThanks for the contribution! The linked issue isn't in the current milestone yet. |
|
Azure Pipelines: Successfully started running 1 pipeline(s). 21 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
Pull request overview
Fixes infrastructure ejection after agent initialization and resolves the owning project root from nested directories.
Changes:
- Chains ejection after unified-manifest adoption and definition reuse.
- Uses upward project discovery.
- Adds project-resolution tests.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
init.go |
Connects init flows to infrastructure ejection. |
init_infra.go |
Resolves the project root before ejection. |
init_infra_test.go |
Tests parent-project and missing-project behavior. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
cli/azd/extensions/azure.ai.agents/internal/cmd/init_infra.go:92
- azd-code-reviewer: This suppresses every validation error from
findFoundryServiceForEject, not only the intended no-Foundry case. For example, unified manifests are adopted when they contain at least one Foundry service, but the eject helper rejects multiple Foundry project services; this branch would then report success without generatinginfra/, recreating the silent failure this PR addresses. Ignore onlyCodeInfraEjectNoFoundryServiceand propagate other errors.
if _, err := findFoundryServiceForEject(rawYAML); err != nil {
return nil
jongio
left a comment
There was a problem hiding this comment.
Left one optional, non-blocking suggestion inline about test coverage for the post-init no-foundry-service skip path.
| if _, err := findFoundryServiceForEject(rawYAML); err != nil { | ||
| if localErr, ok := errors.AsType[*azdext.LocalError](err); ok && | ||
| localErr.Code == exterrors.CodeInfraEjectNoFoundryService { | ||
| return nil |
There was a problem hiding this comment.
Optional, non-blocking: the added tests cover the propagate path (multiple foundry services) and the no-project path, but not this silent-skip branch where azure.yaml exists with no foundry service. A small test here would lock in that post-init eject skips silently while standalone eject still surfaces the same case as an error through ejectInfra.
jongio
left a comment
There was a problem hiding this comment.
Re-reviewed at db9d0e9. The propagation fix now only swallows the no-foundry-service case and surfaces every other validation error, so a malformed or ambiguous manifest no longer skips eject silently. Resolving the root through GetProjectDir matches how the rest of azd finds azure.yaml, and the new tests (parent-project, no-project, multiple-foundry-service) pass locally. My earlier note about a test for the silent-skip branch is still optional, not blocking.
jongio
left a comment
There was a problem hiding this comment.
Reconfirming approval. --infra now chains through ejectInfraAfterInit with upward project resolution, so eject runs after adopt and bare agent.yaml reuse, and from a nested source directory it writes infra/ at the parent project root. The foundry check only swallows the infra_eject_no_foundry_service code, so malformed or multi-service manifests still surface as errors instead of silently skipping. New tests cover the parent-project, no-project, and error-propagation paths, and CI is green.
jongio
left a comment
There was a problem hiding this comment.
Post-init eject now resolves the owning azd project via upward discovery, so --infra works from a nested source directory and writes infra/ beside the project's azure.yaml. The validation-error handling in ejectInfraAfterInit skips only the no-foundry-service case and propagates the multiple-foundry-service and invalid-manifest cases, so --infra no longer reports success without generating infra when the manifest is ambiguous.
Summary
Fixes #9287.
azd ai agent init --infranow generates infrastructure after unified-manifest adoption and bare-definition reuse, including when invoked below the azd project root.Changes
agent initflow: chain infrastructure ejection after successful unifiedazure.yamladoption and bareagent.yamlreuse.infra/beside itsazure.yaml.Manual Validation
--infra --no-prompt; Bicep files were generated in the adopted project.--infrafrom a nested agent source directory; files were generated at the parent project root, with no nestedinfra/.agent.yamlwith--infra --no-prompt; init createdazure.yamland generatedinfra/main.bicep.