fix: preserve IoC singletons during workflow step re-execution#7218
Conversation
69d4747 to
4f47050
Compare
PR Azure#7171 changed workflowCmdAdapter to rebuild the cobra command tree via NewRootCmd on each workflow step. However, NewRootCmd calls registerCommonDependencies on the same container, which re-registers singletons. The golobby IoC container replaces cached instances on re-registration, so any state attached to the original instance (e.g. event handlers for lifecycle hooks on ProjectConfig/ServiceConfig) was silently lost. Fix: introduce newRootCmdSkipRegistration() which builds a fresh cobra command tree without re-registering shared IoC dependencies or re-initializing the platform. The workflow adapter now uses this, so cached singletons (and their event handlers) are preserved while still getting a clean command tree free of stale cobra state. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
4f47050 to
64c0117
Compare
There was a problem hiding this comment.
Pull request overview
This PR fixes a workflow retry regression where rebuilding the Cobra command tree for each workflow step caused IoC singletons to be re-registered and lose attached state (e.g., lifecycle hook handlers).
Changes:
- Added a command-tree builder path that skips dependency re-registration/platform initialization to preserve cached IoC singletons during workflow step re-execution.
- Updated the workflow command adapter to use the no-re-registration root command builder.
- Expanded test coverage to validate singleton preservation and hook/middleware behavior for child-action workflow steps.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| cli/azd/cmd/root.go | Adds newRootCmdWithoutRegistration and gates dependency registration/platform init behind a flag. |
| cli/azd/cmd/container.go | Switches workflow adapter to build commands without re-registering dependencies. |
| cli/azd/cmd/container_test.go | Adds tests proving the singleton replacement regression and validating workflow child-action behavior. |
| cli/azd/cmd/middleware/hooks_test.go | Adds child-action hook tests and introduces a context-aware middleware test helper. |
Azure Dev CLI Install InstructionsInstall scriptsMacOS/Linux
bash: pwsh: WindowsPowerShell install MSI install Standalone Binary
MSI
Documentationlearn.microsoft.com documentationtitle: Azure Developer CLI reference
|
Co-authored-by: rajeshkamal5050 <11532743+rajeshkamal5050@users.noreply.github.com> Agent-Logs-Url: https://github.com/Azure/azure-dev/sessions/5c04d29d-9884-4658-a029-ed340de96935
- Add Unreleased section to CHANGELOG covering merged PRs from 2026-03-19/20: - feat: AI-assisted error troubleshooting category selection (Azure#7216) - feat: CopilotService gRPC extension framework service (Azure#7172) - fix: lifecycle hooks silently not firing in azd up workflow (Azure#7218) - fix: azd update for Linux/macOS shell script and Homebrew (Azure#7213) - fix: azd update on Windows with backup/restore safety (Azure#7166) - fix: azd up --debug/--no-prompt positional arg error (Azure#7212) - fix: PromptSubscription not respecting AZD_DEMO_MODE (Azure#7193) - fix: preflight role check for B2B/guest users (Azure#7174) - Add AZD_DEMO_MODE note to PromptSubscription in extension-framework.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Initial plan * Create changelog for 1.23.11 Co-authored-by: rajeshkamal5050 <11532743+rajeshkamal5050@users.noreply.github.com> Agent-Logs-Url: https://github.com/Azure/azure-dev/sessions/60b5fd27-2a17-468a-a647-1afe3129686a * Revert unrelated extension go.mod/go.sum changes Co-authored-by: rajeshkamal5050 <11532743+rajeshkamal5050@users.noreply.github.com> Agent-Logs-Url: https://github.com/Azure/azure-dev/sessions/60b5fd27-2a17-468a-a647-1afe3129686a * Remove azd update PRs and add #7218 bug fix to changelog Co-authored-by: rajeshkamal5050 <11532743+rajeshkamal5050@users.noreply.github.com> Agent-Logs-Url: https://github.com/Azure/azure-dev/sessions/5c04d29d-9884-4658-a029-ed340de96935 * Update cli/azd/CHANGELOG.md Co-authored-by: JeffreyCA <jeffreychen@microsoft.com> * Fix changelog wording: rebrand #7162 and shorten #7175 Co-authored-by: rajeshkamal5050 <11532743+rajeshkamal5050@users.noreply.github.com> Agent-Logs-Url: https://github.com/Azure/azure-dev/sessions/63b7851c-0a3f-42cd-a989-4263df5f46b5 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: rajeshkamal5050 <11532743+rajeshkamal5050@users.noreply.github.com> Co-authored-by: JeffreyCA <jeffreychen@microsoft.com>
Problem
Fixes microsoft-foundry/foundry-samples#613
PR #7171 changed
workflowCmdAdapterto rebuild the cobra command tree viaNewRootCmdon each workflow step execution. This fixed "context cancelled" errors on retries, but introduced a regression:NewRootCmdcallsregisterCommonDependencieson the same IoC container, which re-registers singletons. The golobby IoC container replaces cached instances on re-registration, so any state attached to the original instance (e.g., event handlers for lifecycle hooks onProjectConfig/ServiceConfig) was silently lost.This means hooks like
preprovision,postprovision,predeploy, etc. could fail to fire when executed as workflow steps insideazd up.Root cause
Confirmed with a test: resolving
*ProjectConfigbefore and after a secondNewRootCmdcall returns different instances (pc1 != pc2).Solution
Introduced
newRootCmdWithoutRegistration()which builds a fresh cobra command tree without re-callingregisterCommonDependencies()orplatform.Initialize(). The workflow adapter now uses this, so:Test coverage
cmd/container_test.goTest_NewRootCmd_ReregistrationReplacesProjectConfig- Proves the bug (step 5:pc1 != pc2) and the fix (step 6:pc3 == pc4) using actual*ProjectConfigsingleton resolutionWorkflowAdapterMiddlewareRunsForChildActions- Verifies commands execute with child action contextWorkflowAdapterMiddlewareChainForAllSteps- Full package, provision, deploy workflow simulationcmd/middleware/hooks_test.goTest_CommandHooks_ChildAction_HooksStillFire- Table-driven test confirming hooks fire for provision/deploy/package/restore withIsChildAction(ctx)=trueTest_CommandHooks_ChildAction_SkipsValidationOnly- Both pre and post hooks fire; only validation is skippedTest_CommandHooks_ChildAction_PreHookError_StopsAction- Failing pre-hook still blocks action in child contextRelates to #7171, #6530